1.进程q
进程呢就相当于一个房子,线程就相当于是房子里面在工作的人,那么一个房子的空间对于房子里面的人来说是共享的,
现在是多进程,也就是说有许多房子,很显然这个房子的空间只属于这个房子,不会属于其他房子,那你应该明白我想说什么了,(一个进程里面资源是共享的,不同进程之间是相当于不同的程序,你QQ的消息微信能度的到嘛?很显然嘛,肯定是不能的,但是啊条件就来了,我擦我现在程序开了多进程,想让两个进程之间的数据交互怎么办?)
解决这一问题的关键就要看你怎么理解进程这个概念了,现在别人qq发给你的东西你要在微信上发出去,怎么办,当然是先存到手机里面啊,然后在发出啊,对了。那么我们的进程queue就是这么一个过程,先把数据序列化存下来,然后在使用。相当于拷贝了一份
from multiprocessing import Queue, Process import os def f(qq): qq.get() qq.put(6) if __name__ == '__main__': q = Queue() q.put(1) q.put(2) p = Process(target=f, args=(q,)) p.start() p.join() print(q.qsize())
2.线程不能给进程传q,所以线程queue的东西其他进程不能使用
3.进程q当作变量传入,其实不是传入,而是克隆进去了。其实是两个q只不过序列化了,因为进程通讯不能在内存里面操作,实际上是两个q不是一个共享q,要注意中间状态
*******************************************pipe********
pipe 相当于是一个管道在使用他之前我们需要把管道的头和尾打通,也就是生成两个对象,然后把一个对象当作参数传到进程里面就可以了
from multiprocessing import Process,Pipe import os def f(liu): print('wocao pid:',os.getpid()) liu.send('wocao',) if __name__ == '__main__': print('start ') Parent_coon, child_coon = Pipe() p = Process(target=f,args=(child_coon,)) p.start() cc = Parent_coon.recv() p.join() print(cc)
4.manage数据共享 pipe
with Manager() as manger:
d = manger.dict()
l = manger.list()
那么manage呢就是简化了的特定的用来在进程之间交互的一个东西,他可以支持列表字典元组变量等等。
如上我们就生成了一个进程交互的字典与列表,使用他需要把他当作参数传入进去即可
# _*_coding:utf-8_*_ # /usr/bin/env python3 # Author:book Miki # 进程之间数据交互用一个中间状态的queue,也就是经进程queue from multiprocessing import Queue, Process, Manager # 导入一个进程queue import threading import queue import os def f(d,l): d['name'] = 'liu' d[1] = 3 l.append(os.getpid()) print(l) if __name__ == '__main__': with Manager() as manger: d = manger.dict() l = manger.list() process_list = [] for i in range(10): P = Process(target=f, args=(d, l)) P.start() process_list.append(P) for i in process_list: i.join() print(d) print(l)
5. 进程锁 进程为什么需要锁呢? 因为啊 所有进程都在共享同一快屏幕,所以需要锁,我们在main里面生成锁的实例,当作参数传进去
同一份pipe代码我们加上锁之后就变成了
from multiprocessing import Process,Pipe, Lock import os def f(l,liu): l.acquire() print('wocao pid:',os.getpid()) liu.send('wocao',) l.release() if __name__ == '__main__': print('start ') lock = Lock() Parent_coon, child_coon = Pipe() p = Process(target=f, args=(lock, child_coon)) p.start() cc = Parent_coon.recv() p.join() print(cc)
进程池的概念就是说同一时间允许多少个进程在运行
在window上启动多进程就必须使用
if __name__ == '__main__':
并且pool要在其里面
pool 里面没有开启开进程的语句,只有apply 串行 apply_async并行这两个, 后者多了一个回调也就是 callback 有了回调,开进程的那个函数的返回值,将会作为参数传入回调的函数里面
# _*_coding:utf-8_*_ # /usr/bin/env python3 # Author:book Miki from multiprocessing import Process,Pool,freeze_support import time import os def f(i): time.sleep(2) print('this process pid is :', os.getpid()) return i+100 def bag(ar): print('-->exec done: ', ar, os.getpid()) if __name__ == '__main__': # freeze_support() print(os.getpid()) pool = Pool(5) for i in range(10): pool.apply_async(func=f,args=(i,), callback=bag) print('end') pool.close() pool.join()
串行的直接开就可以了,没有回调哦。回调的进程的pid号是主函数的pid号。也就是说回调函数是在主函数里面运行的哦。