IPC(Inter-Process Communication)
1、进程之间数据是隔离的,代码示例如下:
from multiprocessing import Process def task(): global n n = 100 print("子进程中:", n) if __name__ == '__main__': p = Process(target=task, ) p.start() n = 10 print("主进程中:", n) 代码运行结果如下: 主进程中: 10 子进程中: 100
实现进程间的通信,用到了队列
2、什么是队列
队列就是先进去的先出来 我们用到的就是multiprocessing中的Queue 创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
底层队列使用管道和锁定实现。
3、Queue方法介绍
Queue(maxsize) #maxsize是队列中允许的最大项数,如果不传参数maxsize则无大小限制 (类Queue中有maxsize=0,if maxsize<=0 则maxsize就没有限制) Queue的实例q具有以下方法: 1.q.get( [ block [ ,timeout ] ] ):返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为, 默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。 如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。 2.q.get_nowait() :同q.get(False)方法。 3.q.put(item [, block [,timeout ] ] ) :将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。block控制阻塞行为, 默认为True。如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。 timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。 4.q.qsize() :返回队列中目前项目的正确数量。此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间, 队列中可能添加或删除了项目。在某些系统上,此方法可能引发NotImplementedError异常。 5.q.empty() :如果调用此方法时 q为空,返回True。如果其他进程或线程正在往队列中添加项目,结果是不可靠的。也就是说, 在返回和使用结果之间,队列中可能已经加入新的项目。 6.q.full() :如果q已满,返回为True. 由于线程的存在,结果也可能是不可靠的(参考q.empty()方法)
4、解决进程间数据隔离的方法,代码示例如下:
from multiprocessing import Queue, Process import os, time def task(queue): print("这个进程id:%s开始放数据了" % os.getpid()) time.sleep(2) queue.put('ly is dsb') print("这个进程id:%s数据放完了" % os.getpid()) if __name__ == '__main__': q = Queue(3) p = Process(target=task, args=(q,)) p.start() print("主进程") res = q.get() print("主进程中取值:",res)
5、多进程间通信
from multiprocessing import Queue, Process import os, time def get_task(queue): print("%s:%s" % (os.getpid(), queue.get())) def put_task(queue): queue.put("%s开始写数据了" % os.getpid()) if __name__ == '__main__': q = Queue(3) p = Process(target=put_task, args=(q,)) p.start() p1 = Process(target=put_task, args=(q,)) p1.start() p2 = Process(target=get_task, args=(q,)) p2.start() p3 = Process(target=get_task, args=(q,)) p3.start()
6、生产者和消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
1.为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,
那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。
为了解决这个问题于是引入了生产者和消费者模式。