博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
管道,数据共享,进程池
阅读量:5294 次
发布时间:2019-06-14

本文共 4530 字,大约阅读时间需要 15 分钟。

内容梗概:     1.管道     2.数据共享     3.进程池     4.回调函数 1.管道     进程间通信(IPC)方式二:管道(不推荐使用,了解即可),会导致数据不安全的情况出现 实例: import time from multiprocessing import Process,Pipe def func(conn1,conn2):     conn1.close()     conn2.close()     # msg = conn2.recv()     msg = conn2.recv()     print(">>",msg) if __name__ == '__main__':     conn1,conn2 = Pipe()     p1 = Process(target=func,args=(conn1,conn2,))     p1.start()     conn1.close()     conn2.close()     conn1.send("嘿嘿")     conn1.send("嘿嘿")     conn1.close()     p1.join() EOFError:接收端两端都关闭的的时候 OSError:发送端关闭后,仍用该发送端发送 2.数据共享     进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的 虽然进程间数据独立,但可以通过Manager实现数据共享,事实上Manager的功能远不止于此 import time from multiprocessing import Process,Manager,Lock def func(dic,lock):     with lock:   #因为数据共享,必须加锁,不认有可能会争抢数据,导致出错         dic["num"] -= 1 if __name__ == '__main__':     m = Manager()     lock = Lock()     dic = m.dict({"num":100})     lis = []     for i in range(100):         p = Process(target=func,args=(dic,lock))         p.start()         lis.append(p)     for el in lis:         el.join()     print(dic["num"]) 3.进程池     进程池的概念,定义一个池子,在里面放上固定数量的进程,有需求来了,就拿一个池中的进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待任务。 如果有很多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行 进程池实例:(创建多个进程和进程池运算的区别) import time from multiprocessing import Process,Manager,Lock,Pool def func(i):     num = 0     for j in range(5):         num += i if __name__ == '__main__':     pool = Pool(4)     #创建多个进程运算     lis = []     start_time = time.time()     for i in range(250):         p = Process(target=func,args=(i,))         p.start()         lis.append(p)     for el in lis:         el.join()     end_time = time.time()     dif_time = abs(start_time - end_time)     print(dif_time) #进程池运算     s_time = time.time()     pool.map(func,range(250))    #此处map所使用的方法,与内置函数用法一致     e_time = time.time()     d_time = abs(s_time - e_time)     print(d_time) 结果:13.073268413543701     0.0017964839935302734     运算速度差距较大,因为创建进程是很浪费资源的 注意:1.,map是异步执行的,并且自带close和join     2.一般约定俗成的是进程池中的进程数量为CPU的数量,工作中要看具体情况来考量。 进程池中常用方法 1.同步方法 import time from multiprocessing import Process,Pool def func(i):     num = 0     for j in range(5):         num += i     time.sleep(0.5)     return num if __name__ == '__main__':     pool = Pool(4)     lis = []     for i in range(10):         res = pool.apply(func,args=(i,)) #         print(res) 2.异步方法 import time from multiprocessing import Process,Pool def func(i):     num = 0     for j in range(5):         num += i     time.sleep(0.5)     print('>>>>>', num)     # return num if __name__ == '__main__':     lis = []     pool = Pool(4)     for i in range(10):         res = pool.apply_async(func,args=(i,))  ## 异步运行,根据进程池中有的进程数,每次最多3个子进程在异步执行,并且可以执行不同的任务,传送任意的参数了     #     lis.append(res)     pool.close()  # 不是关闭进程池,只是锁定     pool.join()     for el in lis:         print(el.get()) 需要注意的是,进程池中的三个进程不会同时开启或者同时结束 而是执行完一个就释放一个进程,这个进程就去接收新的任务。 4.回调函数     回调函数的场景:进程池中任何一个任务一旦处理完了,就立即告知主进程:我好了额,你可以处理我的结果了。主进程则调用一个函数去处理该结果,该函数即回调函数,这是进程池特有的,普通进程没有这个机制,但是我们也可以通过进程通信来拿到返回值,进程池的这个回调也是进程通信的机制完成的。 我们可以把耗时间(阻塞)的任务放到进程池中,然后指定回调函数(主进程负责执行),这样主进程在执行回调函数时就省去了I/O的过程,直接拿到的是任务的结果 import time,os from multiprocessing import Pool,Process def func(n):     print("子进程pid",os.getpid())     return n*2,"约吗?" def call_back_func(x):     print("call_back pid",os.getpid())     print(x)                       #回调函数在写的时候注意一点,回调函数的形参执行有一个,如果你的执行函数有多个返回值,那么也可以被回调函数的这一个形参接收,接收的是一个元祖,包含着你执行函数的所有返回值。 if __name__ == '__main__':     pool = Pool(4)     pool.apply_async(func,args=(2,),callback=call_back_func)   #回调函数只能接受值,不能赋值     print('主进程pid', os.getpid())     pool.close()     pool.join() from threading import Thread def func(n):     print(">>>")     print(n) if __name__ == '__main__':     t = Thread(target=func,args=(5,))     t.start()     t.join()     print("呵呵") import time from threading import Thread class mythread(Thread):     def __init__(self,num):         super().__init__()         self.num = num     def run(self):         print(">>>heiehi") if __name__ == '__main__':     t = mythread(58)     t.start()     time.sleep(0.5)     print("<<>>") import threading,time from threading import Thread,current_thread def func(n):     time.sleep(2)     print('我是子线程,名字是', current_thread().getName())     print('我是子线程,id是', current_thread().ident) if __name__ == '__main__':     t = Thread(target=func,args=(5,))     t.start()     print('我是主线程,id是', current_thread().ident)     print(threading.enumerate())     print(threading.active_count())

转载于:https://www.cnblogs.com/Mixtea/p/10045583.html

你可能感兴趣的文章
关于Vue的组件的通用性问题
查看>>
随机颜色值
查看>>
每日一库:Modernizr.js,es5-shim.js,es5-safe.js
查看>>
目录相关的操作
查看>>
解决虚拟机vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题...
查看>>
C++----练习--引用头文件
查看>>
11.基本包装类型
查看>>
ajax连接服务器框架
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>
利用maven管理项目之POM文件配置
查看>>
用HttpCombiner来减少js和css的请问次数
查看>>
FUSE-用户空间文件系统
查看>>
将tiff文件转化为jpg文件并保存
查看>>
ubuntu 16.04 开机脚本
查看>>
 VS2012 C#调用C++ dll
查看>>
TCL:表格(xls)中写入数据
查看>>
SQL SERVER 2005中如何获取日期(一个月的最后一日、一年的第一日等等)
查看>>
django 学习笔记(转)
查看>>
控制台程序秒变Windows服务(Topshelf)
查看>>
字节流与字符流的区别详解
查看>>