multiprocessing多进程模块
前言 其实 他们的主要区别有以下几点
官方中文文档 threading模块基本使用 多进程与多线程工作的区别多线程工作方式多线程的工作方式实际上在第一篇的时候,我们已经说过了。因为线程必须存在于进程之中,是最小的执行单元,所以你可以将它如此理解: 其实就是不断的往进程这个小房间加人,那么它的优点如下:
而CPython由于GIL锁的设定,所以它的多线程是残缺不全的,因此在很多时候我们依然要用到多进程,虽然这种情况比较少。 多进程工作方式其实就是不断的造出一模一样的小房间,那么它的优点如下:
可以说是唯一优点了,但是我们依然要学习一下 基本使用针对不同平台的进程启动方式 对于进程启动方式来说,其实
import multiprocessing as mp def foo(q): q.put('hello') if __name__ == __main__': # <--- 强烈注意!在windows平台下开多进程一定要在该条语句之下,否则会抛出异常!! mp.set_start_method(spawn') 选择启动方式 q = mp.Queue() 实例化出用于进程间数据共享的管道 p = mp.Process(target=foo,args=(q,)) p.start() 启动进程任务,等待CPU调度执行 print(q.get()) 从管道中拿出数据 p.join() 阻塞至子进程运行完毕 实例化Process类创建子进程 其实感觉上面的方法都已经将本章要写的内容举例了一个七七八八,但是我们接着往下看。与 multiprocessing time print("主进程任务开始处理") task(th_name): 子进程任务开始处理,参数:{0}.format(th_name)) time.sleep(3) 子进程任务处理完毕': <--- Windows平台下必须在该条语句下执行 ==== 实例化出Process类并添加子进程任务以及参数 ==== p1 = multiprocessing.Process(target=task,args=(进程[1]",)) <-- 参数必须添加逗号。因为是args所以会打散,如果不加逗号则不能进行打散会抛出异常 p1.start() 等待CPU调度..请注意这里不是立即执行 主进程任务处理完毕 ==== 执行结果 ==== """ 主进程任务开始处理 主进程任务处理完毕 主进程任务开始处理 子进程任务开始处理,参数:进程[1] 子进程任务处理完毕 """ 这里我们看执行结果, 自定义类继承Process并覆写run方法class Processing(multiprocessing.Process): 自定义类""" def __init__(self,th_name): self.th_name = th_name super(Processing,self).() run(self): .format(self.th_name)) time.sleep(3) : p1 = Processing() p1.start() """ multiprocessing方法大全
进程对象方法大全
守护进程daemon) : p1 = multiprocessing.Process(target=task,1)">,)) p1.daemon = True <-- 设置进程对象p1为守护进程,注意这一步一定要放在start之前。 p1.start() 等待CPU调度..请注意这里不是立即执行 time.sleep(2) ==== 执行结果 ==== # print("子进程任务处理完毕") 可以看到该句没有执行 主进程任务开始处理 主进程任务开始处理 子进程任务开始处理,参数:进程[1] 主进程任务处理完毕 """ ?设置与获取进程名.format(th_name)) obj = multiprocessing.current_process() 获取当前进程对象 获取当前的进程名:{0}.format(obj.name)) 开始设置进程名) obj.name = yyy" 获取修改后的进程名:{0}.format(obj.name)) time.sleep(3: ==== 第一步:实例化出Process类并添加子进程任务以及参数 ==== t1 = multiprocessing.Process(target=task,),name=xxx) t1.start() 主进程名: 直接使用属性 name 主进程任务开始处理 主进程名: MainProcess 主进程任务处理完毕 主进程任务开始处理 子进程任务开始处理,参数:进程[1] 获取当前的进程名:xxx 开始设置进程名 获取修改后的进程名:yyy 子进程任务处理完毕 """ ?锁相关演示 锁的使用和 multiprocessing lock = multiprocessing.Lock() 实例化同步锁对象 # 注意!!! 在Windows平台下,我们应该将锁的实例化放在上面,这样子进程才能拿到锁对象。否则就会抛出异常!!!或者也可以将锁对象传入当做形参进行传入,二者选其一 num = 0 add(): lock.acquire() 上锁 global num for i in range(10000000): 一千万次 num += 1 lock.release() 解锁 sub(): lock.acquire() 一千万次 num -= 1: t1 = multiprocessing.Process(target=add,) t2 = multiprocessing.Process(target=sub,) t1.start() t2.start() t1.join() t2.join() 最终结果: ==== 执行结果 ==== 三次采集 最终结果: 0 最终结果: 0 最终结果: 0 """ from multiprocessing Process,Lock f(l,i): l.acquire() try: hello worldfinally: l.release() : lock = Lock() 将锁实例化后传入 for num in range(10): Process(target=f,args=(lock,num)).start() 三种进程数据共享的方式multiprocessing.Queue 这里一定要使用
进程队列 time Queue,JoinableQueue task_1(q): 正在装东西..) time.sleep(3) q.put(玫瑰花") 正在装东西 q.task_done() 通知对方可以取了 task_2(q): q.join() 阻塞等待通知,接到通知说明队列里里有东西了。 取到了 取东西 : q = JoinableQueue(maxsize=5) 实例化队列 t1 = multiprocessing.Process(target=task_1,args=(q,1)">小明 将队列传进子进程任务中 t2 = multiprocessing.Process(target=task_2,1)">小花) t1.start() t2.start() 正在装东西.. 取到了 玫瑰花 """ ? 为什么线程队列 multiprocessing.Pipe 除开使用进程队列来实现进程间的通信, Pipe task_1(conn1): conn1.send(hello,我是task1print(conn1.recv()) task_2(conn2): (conn2.recv()) conn2.send(我收到了,我是task2: conn1,conn2 = Pipe() 创建两个电话 p1 = multiprocessing.Process(target=task_1,args=(conn1,1)"> 一人一部电话 p2 = multiprocessing.Process(target=task_2,1)">(conn2,)) p1.start() p2.start() p1.join() p2.join() hello,我是task1 我收到了,我是task2 """ multiprocessing.Manager 除了进程队列 Manager task_1(dic): dic[task_1"] = 大帅哥" task_2(dic): dic[task_2大美女print(dic.get()) : with Manager() as m: !!!!! 注意 !!!!!!! 如果对 Manager()中的数据类型进行频繁的操作,而进程又特别多的时候,请使用 Rlock 锁进行处理,这有可能引发线程不安全!!! dic = m.dict() 实例化出了一个字典,除此之外还有很多其他的数据类型 p1 = multiprocessing.Process(target=task_1,args=(dic,1)"> 将字典传进来 p2 = multiprocessing.Process(target=task_2,1)">(dic,)) p1.start() 启动一定要放在with之后 p2.start() p1.join() p2.join() 大帅哥 """ task_1(dic): in range(1000): dic[count"] += 1 task_2(dic): "] -= 1 !!!!! 注意 !!!!!!! 如果对 Manager()中的数据类型进行频繁的操作,而进程又特别多的时候,请使用 Rlock 锁进行处理,这有可能引发线程不安全!!! dic = m.dict({":0}) 传字典 p2 = multiprocessing.Process(target=task_2,)) p1.start() p2.start() p1.join() p2.join() (dic) {'count': -23} """ Manager RLock task_1(dic,lock): with lock: ): dic[ task_2(dic,1)">: lock = RLock() 实例化锁 with Manager() as m: 传字典,传锁 p2 = multiprocessing.Process(target=task_2,1)"> {'count': 0} """ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |