Queue
在上面的例子中我们使用了Queue,可以作为进程通信的共享队列使用。
在上面的程序中,如果你把Queue换成普通的list,是完全起不到效果的。即使在一个进程中改变了这个list,在另一个进程也不能获取到它的状态。
因此进程间的通信,队列需要用Queue。当然这里的队列指的是 multiprocessing.Queue
依然是用上面那个例子,我们一个进程向队列中放入数据,然后另一个进程取出数据
from multiprocessing import
Process, Semaphore, Lock, Queue
import time
from random import
random
buffer = Queue(10)
empty =
Semaphore(2)
full =
Semaphore(0)
lock = Lock()
class
Consumer(Process):
def run(self):
global
buffer, empty, full, lock
while
True:
full.acquire()
lock.acquire()
print 'Consumer get',
buffer.get()
time.sleep(1)
lock.release()
empty.release()
class
Producer(Process):
def run(self):
global
buffer, empty, full, lock
while
True:
empty.acquire()
lock.acquire()
num = random()
print 'Producer put ',
num
buffer.put(num)
time.sleep(1)
lock.release()
full.release()
if __name__ ==
'__main__':
p = Producer()
c = Consumer()
p.daemon = c.daemon = True
p.start()
c.start()
p.join()
c.join()
print 'Ended!'
运行结果:
Producer
put 0.719213647437
Producer
put 0.44287326683
Consumer
get 0.719213647437
Consumer
get 0.44287326683
Producer
put 0.722859424381
Producer
put 0.525321338921
Consumer
get 0.722859424381
Consumer
get 0.525321338921
可以看到生产者放入队列中数据,然后消费者将数据取出来。
get方法有两个参数,blocked和timeout,意思为阻塞和超时时间。默认blocked是true,即阻塞式。
当一个队列为空的时候如果再用get取则会阻塞,所以这时候就需要吧blocked设置为false,即非阻塞式,实际上它就会调用get_nowait()方法,此时还需要设置一个超时时间,在这么长的时间内还没有取到队列元素,那就抛出Queue.Empty异常。
当一个队列为满的时候如果再用put放则会阻塞,所以这时候就需要吧blocked设置为false,即非阻塞式,实际上它就会调用put_nowait()方法,此时还需要设置一个超时时间,在这么长的时间内还没有放进去元素,那就抛出Queue.Full异常。
另外队列中常用的方法
Queue.qsize() 返回队列的大小
,不过在 Mac OS 上没法运行。
原因:
def qsize(self):
# Raises NotImplementedError on Mac OSX
because of broken sem_getvalue()
return self._maxsize –
self._sem._semlock._get_value()
Queue.empty() 如果队列为空,返回True, 反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.get([block[, timeout]])
获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 阻塞式写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item,
False)