python线程间通信的方式,python多线程之间怎么通信
进程间的通信-Queue
1. Queue的使用
你可以使用多处理模块的队列来实现多个进程之间的数据传输。队列本身是一个消息队列程序。首先,用一个小例子来演示队列的工作原理:
#-*-编码:utf-8-*-
fromt多重处理导入队列
#创建一个最多可以接受三条put消息的队列对象
q=队列(3)
Q.put(“消息1”)
Q.put(“消息2”)
print(q.full())
Q.put(“消息3”)
print(q.full())
尝试:
Q.put(消息4 ,真,2)
例外:
Print(消息队列已满,现有消息数:%s%q.qsize())
尝试:
Q.put_nowait(消息5 )
例外:
Print(消息队列已满,现有消息数:%s%q.qsize())
#推荐方式,先判断消息队列是否满,再写
ifnotq.full():
Q.put_nowait(消息6 )
#读取消息时,首先判断消息队列是否为空。阅读时
ifnotq.empty():
foriinrange(q.qsize()):
Print(q.get_nowait())运行如下:
错误的
真实的
消息队列已满,现有消息数:3
消息队列已满,现有消息数:3
1条消息
消息2
3说明新闻
在初始化Queue()对象时(例如:q=Queue()),如果括号中没有指定可接受消息的个数,或者个数为负数,则表示可接受消息的个数没有上限(直到内存结束);
Queue.qsize():返回当前队列中包含的消息数;
Queue.empty():如果队列为空,则返回True,否则返回false
Queue.full():如果队列已满,则返回True,否则返回False;
Queue.get([block[,timeout]]):获取队列中的消息,然后将其从队列中移除。block的默认值为True;
1)如果使用缺省值block,并且没有设置超时(单位秒),如果消息队列为空,那么程序将被阻塞(停止在读取状态),直到从消息队列中读取消息。如果设置了超时,它将等待超时秒,如果没有消息被读取,它将抛出一个队列。“Empty”异常;
2)如果block值为假,如果消息队列为空,则‘Queue。将立即引发“Empty”异常;
queue . get _ nowait():quite queue . get(false);
Queue.put (item,[block [,timeout]]):将item消息写入队列,block默认值为True;
1)如果block使用默认值且未设置timeout(单位秒),则如果消息队列中没有写入空间,程序将被阻塞(停止在写入状态),直到消息队列中有可用空间。如果设置了超时,它将等待超时秒,如果没有空间,它将抛出一个队列。“完整”异常;
2)如果block值为False,消息队列将立即抛出一个 queue。如果没有空间可写,则出现“Full”异常;
queue . put _ nowait(item):quite queue . put(item,False););
2. Queue实例
我们以Queue为例,在父进程中创建两个子进程,其中一个到q。
ueue里写数据,一个从Queue里读数据:
frommultiprocessingimportProcess运行结果为:frommultiprocessingimportQueue
importos
importtime
importrandom
#写数据进程执行的代码
defwrite(q):
forvaluein["A","B","C"]:
print("Put%stoQueue"%value)
q.put(value)
time.sleep(random.random())
#读取数据进程的代码
defread(q):
whileTrue:
ifnotq.empty():
value=q.get(True)
print("Get%sfromQueue"%value)
time.sleep(random.random())
else:
break
if__name__=='__main__':
#父进程创建Queue,并传递给各个子进程
q=Queue()
pw=Process(target=write,args=(q,))
pr=Process(target=read,args=(q,))
#启动子进程pw,写入
pw.start()
#等待pw结束
pw.join()
#启动子进程pr,读取
pr.start()
pr.join()
print("所有数据都写入并且读完")
PutAtoQueue所有数据都写入并且读完。PutBtoQueue
PutCtoQueue
GetAfromQueue
GetBfromQueue
GetCfromQueue
3. 进程池中的Queue
如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:
RuntimeError: Queue objects should only be shared between processes through inheritance.
#coding=utf-8运行结果为:frommultiprocessingimportManager
frommultiprocessingimportPool
importos
importtime
importrandom
defreader(q):
print("reader启动(%d),父进程为(%d)"%(os.getpid(),os.getppid()))
foriinrange(q.qsize()):
print("reader从Queue获取到的消息时:%s"%q.get(True))
defwriter(q):
print("writer启动(%d),父进程为(%d)"%(os.getpid(),os.getppid()))
foriin"Se7eN_HOU":
q.put(i)
if__name__=='__main__':
print("-------(%d)Start-------"%os.getpid())
#使用Manager中的Queue来初始化
q=Manager().Queue()
po=Pool()
#使用阻塞模式创建进程,这样就不需要在reader中使用死循环了,可以让writer完全执行完成后,再用reader去读取
po.apply(writer,(q,))
po.apply(reader,(q,))
po.close()
po.join()
print("-------(%d)End-------"%os.getpid())
-------(880)Start-------相关推荐:writer启动(7744),父进程为(880)
reader启动(7936),父进程为(880)
reader从Queue获取到的消息时:S
reader从Queue获取到的消息时:e
reader从Queue获取到的消息时:7
reader从Queue获取到的消息时:e
reader从Queue获取到的消息时:N
reader从Queue获取到的消息时:_
reader从Queue获取到的消息时:H
reader从Queue获取到的消息时:O
reader从Queue获取到的消息时:U
-------(880)End-------
Python中的进程池是什么
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。