《Python》进程收尾线程初识

  from multiprocessing import Manager

  把所有实现了数据共享的比较便捷的类都重新又封装了一遍,并且在原有的multiprocessing基础上增加了新的机制list、dict

  机制:支持的数据类型非常有限

    list、dict都不是数据安全的,需要自己加锁来保证数据安全

from multiprocessing import Manager,Process,Lock

def work(d,lock):
    with lock:
        d[‘count‘] -= 1

if __name__ == ‘__main__‘:
    lock = Lock()
    with Manager() as m:   # m = Manager()
        dic = m.dict({‘count‘:100})
        p_lst = []
        for i in range(10):
            p = Process(target=work, args=(dic, lock))
            p_lst.append(p)
            p.start()
        for p in p_lst:
            p.join()
        print(dic)
#{‘count‘: 90}
with ......
    一大段语句
dis模块
python的上下文管理
在执行一大段语句之前,自动做某个操作  open
在执行一大段语句之后,自动做某个操作  close

面向对象的魔术方法(双下杠杠方法)
# 回调函数 in Pool

import os
from multiprocessing import Pool

def func(i):
    print(‘第一个任务‘, os.getpid())
    return ‘*‘*i

def call_back(res):   #回调函数
    print(‘回调函数:‘, os.getpid())
    print(‘res--->‘, res)

if __name__ == ‘__main__‘:
    p = Pool()
    print(‘主进程‘, os.getpid())
    p.apply_async(func, args=(1,), callback=call_back)
    p.close()
    p.join()

  func执行完毕之后执行callback函数

  func的返回值会作为callback的参数

  回调函数是在主进程中实现的

  应用场景:子进程有大量运算要做,回调函数等待结果做简单处理

import re
from urllib.request import urlopen
from multiprocessing import Pool

url_lst = [
    ‘http://www.baidu.com‘,
    ‘http://www.sohu.com‘,
    ‘http://www.sogou.com‘,
    ‘http://www.4399.com‘,
    ‘http://www.cnblogs.com‘,
]

def get_url(url):
    response = urlopen(url)
    ret = re.search(‘www\.(.*?)\.com‘, url)
    print(‘%s finished‘ % ret.group(1))
    return ret.group(1),response.read()

def call(content):
    url,con = content
    with open(url+‘.html‘, ‘wb‘)as f:
        f.write(con)
if __name__ == ‘__main__‘:
    p = Pool()
    for url in url_lst:
        p.apply_async(get_url,args=(url,),callback=call)
    p.close()
    p.join()

子进程去访问网页,主进程处理网页的结果

二、线程理论基础

  进程是计算机中最小的资源分配单位,进程对于操作系统来说还具有一定的负担

  创建一个进程,操作系统分配的资源大约有:代码,数据,文件等

1、为什么要有线程

  线程是轻量级的概念,他没有属于自己的进程资源,一条线程只负责执行代码,没有自己独立的代码、数据以及文件

  线程是计算机中能被CPU调用的最小的单位,当前大部分计算机中的CPU都是执行的线程中的代码

  线程与进程之间的关系:每一个进程中都至少有一条线程在工作

线程的特点:

  同一个进程中的所有线程的资源是共享的

  轻量级, 没有自己的资源

进程与线程之间的区别:    

  占用的资源、调度的效率、资源是否共享

线程的并行问题:

  线程可以并行:java、c++,c#等

  在cpython中,一个进程中的多个线程是不可以并行的

  原因是:Cpython解释器内部有一把全局解释器锁GIL,所以线程不能充分利用多核,同一时刻同一进程中的线程只有一个能被cpu执行

  GIL锁确实是限制了你程序的效率,但目前可以帮助你提高线程之间切换的效率

  如果是想写高计算型的就要多进程或者换一个解释器

2、threading 模块

# 并发

import os
from threading import Thread

def func(i):
    print(‘子线程:‘, i, os.getpid())

print(‘主线程‘, os.getpid())
for i in range(10):
    t = Thread(target=func, args=(i,))
    t.start()
# 进程和线程的差距

import os
import time
from threading import Thread
from multiprocessing import Process

def func(i):
    print(‘子:‘, os.getpid())

if __name__ == ‘__main__‘:
    start = time.time()
    t_lst = []
    for i in range(100):
        t = Thread(target=func, args=(i,))
        t.start()
        t_lst.append(t)
    for t in t_lst:
        t.join()
    end = time.time()-start

    start = time.time()
    t_lst = []
    for i in range(100):
        p = Process(target=func, args=(i,))
        p.start()
        t_lst.append(p)
    for p in t_lst:
        p.join()
    end2 = time.time()-start
    print(end, end2)
#0.0279843807220459 13.582834720611572
# 线程间的数据共享

from threading import Thread

num = 100
def func():
    global num
    num -= 1            #每个线程都-1

t_lst = []
for i in range(100):
    t = Thread(target=func)   #创建一百个线程
    t.start()
    t_lst.append(t)
for t in t_lst:
    t.join()
print(num)   #0 

Thread 类的其他用法

Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。

threading模块提供的一些方法:
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

from threading import currentThread,Thread
def func():
    time.sleep(2)

t = Thread(target=func)
t.start()
print(t.is_alive())    #True(判断线程是否活着)
print(t.getName())  #Tread-1
t.setName(‘tt‘)
print(t.getName())   #tt(改名字)

def func():
    print(‘子线程:‘, currentThread().ident)
    time.sleep(2)
print(‘主线程:‘,currentThread().ident)
t = Thread(target=func)
t.start()
#currentThread().ident返回线程的pid

from threading import enumerate
def func():
    print(‘子进程:‘, currentThread().ident)
    time.sleep(2)

print(‘主进程:‘, currentThread().ident)
for i in range(10):
    t = Thread(target=func)
    t.start()
print(len(enumerate()))
#enumerate()返回一个包含正在运行的线程的list,len(list)

from threading import activeCount
def func():
    print(‘子线程:‘, currentThread().ident)
    time.sleep(2)

print(‘主线程:‘, currentThread().ident)
for i in range(10):
    t = Thread(target=func)
    t.start()
print(activeCount())
#activeCount()返回正在运行的线程数量,与len(threading.enumerate())有相同的结果

示例

3、守护线程

import time
from threading import Thread

def func():
    while True:
        time.sleep(1)
        print(123)

def func2():
    print(‘func2 start‘)
    time.sleep(3)
    print(‘func2 end‘)

t1 = Thread(target=func)
t2 = Thread(target=func2)
t1.setDaemon(True)
t1.start()
t2.start()
print(‘主线程代码结束‘)
# func2 start
#主线程代码结束
#123
#123
#func2 end

  守护线程 是在主线程代码结束之后,再等待子线程执行结束后才结束

  主线程结束  就意味着主进程结束

  主线程等待所有的线程结束

  主线程结束了以后  守护线程会随着主进程的结束而随之结束  不是随着代码的结束而结束

#################################################################################

线程线程和进程之间的关系    每个进程内都有一个线程    线程是不能独立存在的线程和进程之间的区别    同一个进程中线程之间的数据是共享的    进程之间的数据是隔离的    线程是被cpu执行的最小单位        操作系统调度    进程是计算机中最小的资源分配单位python    GIL锁 全局解释器锁 全局锁         cpython解释器中的        锁线程 :同一时刻同一个进程只会有一个线程访问CPU            锁的是线程而不是数据    当程序是高IO型的 多线程    当程序是高计算(CPU)型的 多进程        cpu*1 ~ cpu*2

threadingThread    守护线程 :主线程结束之后才结束

socket_server IO多路复用 + 多线程框架 并发的效果 :多线程、协程的概念 flask爬虫 :线程池 协程

set、dict、list生成器面向对象的进阶 :魔术方法管道socket_server的源码

原文地址:https://www.cnblogs.com/yzh2857/p/9699875.html

时间: 2024-10-04 08:09:46

《Python》进程收尾线程初识的相关文章

Python编程(二):Python进程、线程那点事儿

多进程,多线程编程 系统程序员.运维开发程序员在面试的时候经常会被问及一个常见问题: 进程是什么,线程是什么,进程和线程有什么区别? 不得不承认,这么多年了.这个问题依旧是个很难以招架的问题,简单地说: 进程和线程有很多类似的性质,他们都可以被CPU作为一个单元进行调度,他们都拥有自己独立的栈(stack)等等.因此线程也被称作LWP(Lightweight Process,轻量级进程):对应的进程也可以被称作为HWP(Heavyweight Process,重量级进程),从线程的角度看,进程就

python 进程、线程 (二)

一.多线程与多进程的对比 在python 进程.线程 (一)中简单的说过,CPython中的GIL使得同一时刻只能有一个线程运行,即并发执行.并且即使是多核CPU,GIL使得同一个进程中的多个线程也无法映射到多个CPU上运行,这么做最初是为了安全着想,慢慢的也成为了限制CPython性能的问题. 就像是一个线程想要执行,就必须得到GIL,否则就不能拿到CPU资源.但是也不是说一个线程在拿到CPU资源后就一劳永逸,在执行的过程中GIL可能会释放并被其他线程获取,所以说其它的线程会与本线程竞争CPU

python\进程和线程2

1  GIL全局解释器锁定义 定义:在一个线程拥有了解释器的访问权后,其他的所有线程都必须等待他释放解释器的访问权,即这些线程的下一条指令并不会互相影响. 缺点:多处理器退化为单处理器 优点:避免大量的加锁解锁操作 无论你启多少个线程,你有多少个cpu,python在执行一个进程的时候会淡定的在同一时刻只允许一个线程运行. Python是无法利用多核cpu实现多线程的 总结: 对于计算密集型任务,python的多线程并没有用 对于IO密集型任务,python的多线程是有意义的 python使用多

python进程、线程、协程

进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等. 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构--进程控制块. 进程就是一个程序在一个数据集上的一次动态执行过程. 进程一般由程序.数据集.进程控

Python进程与线程及GIL(全局解释器锁)

MarkdownPad Document 进程与线程 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种一个程序在一个数据集上的一次动态执行过程就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本:进程是程序的一次执行活动,属于动态概念.进程一般由程序.数据集.进程控制块三部分组成. 有了进程为什么还要有线程呢? 因为进程还是有缺陷的: 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了 进程在执行的过程中如果阻塞,例

Python进程、线程、协程详解

进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等. 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构——进程控制块. 进程就是一个程序在一个数据集上的一次动态执行过程. 进程一般由程序.数据集.进程控

[ Python - 14 ] python进程及线程编程

什么是进程: 简单来讲,进程就是操作系统中运行的程序或任务,进程和程序的区别在于进程是动态的,而程序是静态的.进程是操作系统资源管理的最小单位. 什么是线程: 线程是进程的一个实体,是cpu调度和分派的最小单位,它是比进程更小的能独立运行的基本单位,线程本身不拥有资源,但它可以与同属于一个进程的线程共享进程的资源所拥有的全部资源. python多线程编程与GIL: 为了更有效的利用多核处理,就出现了多线程编程,但是问题是线程间数据的一致性和状态的同步如果得到保证,因此python解析器引入了GI

Python 进程、线程、协程、锁机制,你知多少?

1.python的多线程到底有没有用? 2. 为什么在python里推荐使用多进程而不是多线程 3.进程.线程.协程.各种锁

python进程、线程、协程以及几种自定义线程池

Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time    def show(arg):     time.sleep(1)     print 'thread'+str(arg)    for i in range(10):     t = threading.Thread(target=show, args