一、管道
管道:进程与进程之间能相互通信
通信原理:是基于管道双向通信
from multiprocessing import Pipe, Process conn1, conn2 = Pipe() conn1.send("123456") print(conn2.recv())
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from multiprocessing import Pipe, Process def func(conn): while True: msg = conn.recv() if msg == None: break print(msg) if __name__ == '__main__': conn1, conn2 = Pipe() Process(target=func, args=(conn1,)).start() for i in range(10): conn2.send("吃了么") conn2.send(None) """ #第二种: def func(conn1, conn2): conn2.close() while True: try: msg = conn1.recv() print(msg) except EOFError : conn1.close() break if __name__ == '__main__': conn1, conn2 = Pipe() Process(target=func, args=(conn1,conn2)).start() conn1.close() for i in range(10): conn2.send("吃了么") conn2.close() # 疑问:主进程关闭通道不会影响子进程接收数据 # # ********应该特别注意管道端点的正确管理问题,如果是生产者或者消费者中都没有使用管道的某个端点,就应该将它关闭 这也说明为何在生产中关闭了管道的输出端,在消费者中关闭管道的输入端。如果忘记执行这些步骤,程序可能在消费者中 的recv()操作阻塞。管道是由操作系统进行引用计数的,必须在所有进程中关闭管道后才能生成EOFError异常 因此,在生产中关闭管道不会有任何效果,除非消费者也关闭了相同的管道端点 # """
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from multiprocessing import Pipe, Process, Lock import random, time def producer(con, pro, name, food): con.close() for i in range(4): time.sleep(random.randint(1, 3)) f = "%s生产%s%s" % (name, food, i) print(f) pro.send(f) pro.close() def consumer(con, pro, name): pro.close() while True: try: # lock.acquire() food = con.recv() # lock.release() print("%s吃了%s" % (name, food)) time.sleep(random.randint(1, 3)) except EOFError: print("%s吃完啦" % name) con.close() break if __name__ == '__main__': con, pro = Pipe() # lock = Lock() p = Process(target=producer, args=(con, pro, "猪狗", "泔水")) p.start() c = Process(target=consumer, args=(con, pro, "逗比")) c1 = Process(target=consumer, args=(con, pro, "坦克" )) c.start() c1.start() con.close() pro.close() # Pipe 管道数据不安全(可能发生多进程抢一个数据)枷锁来控制抢资源对象 管道属于最底层的东西 # 队列是 管道+锁 所以比较安全,一般用队列 """ 应该特别注意管道端点的正确管理问题,如果是生产者或者消费者中都没有使用管道的某个端点,就应该将它关闭 这也说明为何在生产中关闭了管道的输出端,在消费者中关闭管道的输入端。如果忘记执行这些步骤,程序可能在消费者中 的recv()操作阻塞。管道是由操作系统进行引用计数的,必须在所有进程中关闭管道后才能生成EOFError异常 因此,在生产中关闭管道不会有任何效果,除非消费者也关闭了相同的管道端点 """
二、进程之间的数据共享
模块:Manager
from multiprocessing import Manager, Process, Lock
def main(dic, lock): lock.acquire() dic["count"] -= 1 lock.release() print(dic) if __name__ == '__main__': lock = Lock() # 牺牲效率变成串行(同步),但是安全 m = Manager() # 可以把数据共用多个进程共享,但是会发生多个子进程抢同一个资源,造成数据混乱,使用必须加锁 dic = m.dict({"count": 100}) p_lis = [] for i in range(50): p = Process(target=main, args=(dic, lock)) p_lis.append(p) # 把对象添加到列表 p.start() for i in p_lis: i.join() # 把每个对象添加join,所有子进程结束,主进程才运行 print("主进程:", dic)
三、进程池