总体上来说,当需要在进程间通信的时候需要使用multiprocessing.Queue; 当在同一个进程当中,而需要多线程之间通信的时候,可以使用Queue.Queue;而至于collections.deque一般就是在同一个线程当中,作为一种数据结构来使用的。下面分别讲述一下它们的用法:
multiprocessing.Queue
multiprocessing提供了两种进程间通信机制,一种是我们要说的Queue,另外一种是Pipe。而实际上Queue也是通过Pipe来实现的。具体可以参考进程间通信 Queue常用methods:
- Queue.qsize(): 返回queue中item的数量,注意这个数量并不准确, not reliable
- Queue.empty(): return True if queue is empty, not reliable
- Queue.full(): return True if queue is full, not reliable
- Queue.put(item[, block[, timeout]]): block表示是否阻塞,默认为True即阻塞,如果设定了timeout,则阻塞timeout时长,如果仍然没有空余的slot,则raise Queue.full exception。如果block=False,那么就不阻塞,当queue full时,直接报Queue.full exception。
- Queue.put_nowait(item): Equivalent to put(item, False)
- Queue.get([block[, timeout]])
- Queue.get_nowait(): Equivalent to get(False)
示例:
1
2
3
4
5
6
7
8
9
10
11from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print q.get()
p.join()
需要注意的是Queue不提供join()和task_done(),因此在producer process中无法确保所有的task均已经被处理, 如果需要join and task_done就需要使用multiprocessing.JoinableQueue,详情参看JoinableQueue
Queue.Queue
Queue.Queue通常用于同一个进程中的不同线程间的通信,其提供的方法与multiprocessing.Queue类似,但是多出了两个methods如下:
- task_done(): 用于告知任务完成
- join(): 用于等待队列中所有的任务完成。具体使用见下图
collections.deque
主要用于队列这种数据结构,通过append和popleft来实现队列的FIFO机制。常用方法如下:
- extendleft
- appendleft
- popleft
- extend
- append
- pop
具体参考官网
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50> from collections import deque
'ghi') # make a new deque with three items > d = deque(
d: # iterate over the deque's elements > for elem in
... print elem.upper()
G
H
I
'j') # add a new entry to the right side > d.append(
'f') # add a new entry to the left side > d.appendleft(
# show the representation of the deque > d
deque(['f', 'g', 'h', 'i', 'j'])
# return and remove the rightmost item > d.pop()
'j'
# return and remove the leftmost item > d.popleft()
'f'
# list the contents of the deque > list(d)
['g', 'h', 'i']
0] # peek at leftmost item > d[
'g'
1] # peek at rightmost item > d[-
'i'
# list the contents of a deque in reverse > list(reversed(d))
['i', 'h', 'g']
'h' in d # search the deque >
True
'jkl') # add multiple elements at once > d.extend(
> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
1) # right rotation > d.rotate(
> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
1) # left rotation > d.rotate(-
> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
# make a new deque in reverse order > deque(reversed(d))
deque(['l', 'k', 'j', 'i', 'h', 'g'])
# empty the deque > d.clear()
# cannot pop from an empty deque > d.pop()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
d.pop()
IndexError: pop from an empty deque
'abc') # extendleft() reverses the input order > d.extendleft(
> d
deque(['c', 'b', 'a'])