python之 《进程之间数据交互和进程池》

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号。也就是说回调函数是在主函数里面运行的哦。



原文地址:https://www.cnblogs.com/BookMiki/p/10252541.html