2
import threading
import Queue

q = Queue.Queue()
class Worker( threading.Thread ):
    def __init__( self, q ):
        threading.Thread.__init__( self )
        self.q = q

    def run( self ):
        while True:
            print '%s waiting for data' % self.getName()
            data = self.q.get()
            print '%s data fetched from queue %s' % ( self.getName(), data )
            if data == 'shutdown':
                print '%s shutting down in %s' % ( self.getName(), self )
                return
            print '%s received a message: %s' % ( self.getName(), data )

    def stop( self ):
        self.q.put( "shutdown" )

#        self.join()  # If I uncomment this line, then sometimes the program does not complete.


def broadcast_event( data ):
    q.put( data )

t1 = Worker( q )
t2 = Worker( q )
t1.start()
t2.start()
broadcast_event( "first event" )
broadcast_event( "second event" )

t1.stop()
t2.stop()

我试图理解 python 中的线程,但我被困在多线程队列示例中。我正在尝试做的事情:-

  1. 使用单个队列对象创建 2 个线程
  2. 现在,我将 2 个不同的数据条目放入队列中(使用broadcast_event函数)
  3. 现在,在 stop 方法中,有一个注释行,我将线程加入到主程序中。

但是,当我取消注释该self.join行时,程序挂断并永远运行。但是,如果我删除self.join,它会完美运行。

我想了解我如何尝试使用加入是否有问题。

4

2 回答 2

3

你的问题是两个线程都使用同一个队列。死锁场景是:

  1. 主线程'shutdown'发送t1.stop()
  2. t2'shutdown'q
  3. 主线程 joins t1,它永远等待新消息。

您可以通过创建 2 个队列或执行前两条shutdown消息然后执行两个连接来解决此问题。

于 2013-04-16T12:20:04.687 回答
1

问题是您有两个线程使用一个队列。当您put在队列中有一条消息时,您无法判断哪个线程将使用它。当您调用stop(),添加"shutdown"到队列中时,它可能会被任何线程消耗,不一定是您想要的线程。

结果可能是另一个线程正在退出,而您join输入了错误的线程。

一种可能的解决方案是先将shutdown队列放入 N 次(N = 线程数),然后将它们全部加入。

for i in range(N):
  q.put("shutdown")
for t in threads:
  t.join()

一个更好、更健壮的解决方案是避免通过队列传递关闭消息。您可以self.should_stop为此使用一个属性,定期在run.

于 2013-04-16T12:25:18.067 回答