多个进程读取和写入队列,直到对象属性为真

时间:2017-05-10 09:35:12

标签: python python-2.7 queue multiprocessing

我有一个对象实例,它包含两个队列,一个输入队列和一个输出队列。父进程会生成几个在队列上工作的子进程。

我的要求是:

  • 应该可以随时填充输入队列(下面代码中的函数fill()
  • 子进程应该处理输入队列中的项目。如果输入队列为空,则应等待输入队列填充(函数echo()
  • 如果项目非空(函数read()),则应从输出队列中读取
  • 如果共享关闭标志(属性self._shutdown)设置为true,则所有进程应该结束而不是等待队列项

以下是我目前的代码:

Python 2.7最小示例

from multiprocessing import Queue, Process, Value
from ctypes import c_bool
from Queue import Empty

class A(object):

  def __init__(self):
    self._shutdown = Value(c_bool, False)
    self._input_queue = Queue()
    self._output_queue = Queue()

  def echo(self):
    while True:
      if self._shutdown.value == True: break
      try:
        item = self._input_queue.get(True, timeout=1)
      except Empty:
        continue
      print "[echo] read from input qeue: ", item
      print "[echo] put into output queue: ", item*2
      self._output_queue.put(item*2)

  def fill(self):
    for item in xrange(1,6):
      print "[fill] put into input queue: ", item
      self._input_queue.put(item)

  def read(self):
    while True:
      if self._shutdown.value == True: break
      try:
        item = self._output_queue.get(True, timeout=1)
      except Empty:
        continue
      print "[read] got from output queue: ", item

a = A()

p1 = Process(target=a.echo)
p2 = Process(target=a.echo)

p1.start()
p2.start()

a.fill()
a.read()
a._shutdown.value = True

上面脚本的输出是正确的:

[fill] put into input queue:  1
[fill] put into input queue:  2
[fill] put into input queue:  3
[fill] put into input queue:  4
[fill] put into input queue:  5
[echo] read from input qeue:  1
[echo] put into output queue:  2
[echo] read from input qeue:  2
[echo] put into output queue:  4
[echo] read from input qeue:  3
[echo] put into output queue:  6
[read] got from output queue:  2
[echo] read from input qeue:  4
[read] got from output queue:  6
[echo] put into output queue:  8
[echo] read from input qeue:  5
[echo] put into output queue:  10
[read] got from output queue:  8
[read] got from output queue:  4
[read] got from output queue:  10

除了它死锁并且过程永远不会完成。似乎这些进程相互阻挡。我的问题是:

为什么我的代码确实死锁,我该怎么办才能阻止这种情况?

1 个答案:

答案 0 :(得分:2)

你的a.read()是主线​​程中的同步调用,导致永久的while循环直到self._shutdown.valueTrue。你正在a.read下的那一行发生。所以行a._shutdown.value = True永远不会执行。然后只有更改会反映在p1p2内。所以发生的事情只有p1(process 1)p2(process 2)和{{1}永远在跑。