进程:
之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
进程间通信
用Queue模块:
IPC(Inter-Process Communication)
队列
概念介绍
队列是先进先出
必须put放进东西后 才能get来取值
创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
Queue([maxsize])
创建共享的进程队列。
参数 :maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。
底层队列使用管道和锁定实现。
Queue([maxsize])
创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中。
Queue的实例q具有以下方法:
q.get( [ block [ ,timeout ] ] )
返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。
q.get_nowait( )
同q.get(False)方法。
q.put(item [, block [,timeout ] ] )
将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。block控制阻塞行为,默认为True。如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。
q.qsize()
返回队列中目前项目的正确数量。此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。在某些系统上,此方法可能引发NotImplementedError异常。
q.empty()
如果调用此方法时 q为空,返回True。如果其他进程或线程正在往队列中添加项目,结果是不可靠的。也就是说,在返回和使用结果之间,队列中可能已经加入新的项目。
q.full()
如果q已满,返回为True. 由于线程的存在,结果也可能是不可靠的(参考q.empty()方法)。。
队列中的进程的内容是共享的 因为不同的进程的数据是隔离的 我们可以用队列 让他们之间的数据进行共享
在进程中使用队列可以完成双向通信
from multiprocessing import Process ,Queue q = Queue(10) try: q.get_nowwait() # 如果你用 nowwait的话你的获取嗯u过没有就不会阻塞就会报错 except: print('queue.Empty') q.get() for i in range(10): q.get(i) print(q.qsize(10))
from multiprocessing import Process ,Queue q = Queue(10) # 创建一个可以存放10个值的队列 # try: # q.get_nowwait() # except: # print('queue.Empty') # # q.get() for i in range(10): q.put(i) print(q.qsize()) # 获取你的队列可以存放的最大值 print(q.full()) # 判定是不是满了 返回的值布尔值 # q.put(111) # 给这个队列放进值 # print(q.grt()) print('*'*10) print(q.empty()) # 判定队列是不是为空 返回的也是布尔值
生产者消费者模型
解决数据供需不平衡的情况
队列是进程安全的 内置了锁来保证队列中的每一个数据都不会被多个进程重复取
import time import random from multiprocessing import Process,Queue 生产者消费者模型 解决数据供需不平衡的情况 队列是进程安全的 内置了锁来保证队列中的每一个数据都不会被多个进程重复取 def consumer(q,name): while True: food = q.get() if food == 'done':break time.sleep(random.random()) print('%s吃了%s'%(name,food)) def producer(q,name,food): for i in range(10): time.sleep(random.random()) print('%s生产了%s%s'%(name,food,i)) q.put('%s%s'%(food,i)) if __name__ == '__main__': q = Queue() p1 = Process(target=producer,args=[q,'Egon','泔水']) p2 = Process(target=producer,args=[q,'Yuan','骨头鱼刺']) p1.start() p2.start() Process(target=consumer,args=[q,'alex']).start() Process(target=consumer,args=[q,'wusir']).start() p1.join() p2.join() q.put('done') q.put('done')
import time import random from multiprocessing import Process,JoinableQueue def consumer(q,name): while True: food = q.get() time.sleep(random.random()) print('%s吃了%s'%(name,food)) q.task_done() def producer(q,name,food): for i in range(10): time.sleep(random.random()) print('%s生产了%s%s'%(name,food,i)) q.put('%s%s'%(food,i)) q.join() # 等到所有的数据都被taskdone才结束 if __name__ == '__main__': q = JoinableQueue() p1 = Process(target=producer,args=[q,'Egon','泔水']) p2 = Process(target=producer,args=[q,'Yuan','骨头鱼刺']) p1.start() p2.start() c1 = Process(target=consumer,args=[q,'alex']) c2 = Process(target=consumer,args=[q,'wusir']) c1.daemon = True c2.daemon = True c1.start() c2.start() p1.join() p2.join() # producer # put # 生产完全部的数据就没有其他工作了 # 在生产数据方 : 允许执行q.join # join会发起一个阻塞,直到所有当前队列中的数据都被消费 # consumer # get 获取到数据 # 处理数据 # q.task_done() 告诉q,刚刚从q获取的数据已经处理完了 # consumer每完成一个任务就会给q发送一个taskdone # producer在所有的数据都生产完之后会执行q.join() # producer会等待consumer消费完数据才结束 # 主进程中对producer进程进行join # 主进程中的代码会等待producer执行完才结束 # producer结束就意味着主进程代码的结束 # consumer作为守护进程结束 # consumer中queue中的所有数据被消费 # producer join结束 # 主进程的代码结束 # consumer结束 # 主进程结束
Queue([maxsize])
创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中。
Queue的实例q具有以下方法:
q.get( [ block [ ,timeout ] ] )
返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。
q.get_nowait( )
同q.get(False)方法。
q.put(item [, block [,timeout ] ] )
将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。block控制阻塞行为,默认为True。如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。
q.qsize()
返回队列中目前项目的正确数量。此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。在某些系统上,此方法可能引发NotImplementedError异常。
q.empty()
如果调用此方法时 q为空,返回True。如果其他进程或线程正在往队列中添加项目,结果是不可靠的。也就是说,在返回和使用结果之间,队列中可能已经加入新的项目。
q.full()
如果q已满,返回为True. 由于线程的存在,结果也可能是不可靠的(参考q.empty()方法)。
JoinableQueue([maxsize])
创建可连接的共享进程队列。这就像是一个Queue对象,但队列允许项目的使用者通知生产者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。
JoinableQueue的实例p除了与Queue对象相同的方法之外,还具有以下方法:
q.task_done()
使用者使用此方法发出信号,表示q.get()返回的项目已经被处理。如果调用此方法的次数大于从队列中删除的项目数量,将引发ValueError异常。
q.join()
生产者将使用此方法进行阻塞,直到队列中所有项目均被处理。阻塞将持续到为队列中的每个项目均调用q.task_done()方法为止。
下面的例子说明如何建立永远运行的进程,使用和处理队列上的项目。生产者将项目放入队列,并等待它们被处理。
from multiprocessing import Process,JoinableQueue import time,random,os def consumer(q): while True: res=q.get() time.sleep(random.randint(1,3)) print('