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中的线程,并且我陷入了多线程队列示例中。 我想做什么: -
broadcast_event
函数)但是,当我取消注释self.join
行时,程序会挂起并永远运行。但是,如果我删除了self.join
,则效果非常好。
我想了解我是否尝试使用加入是否存在问题。
答案 0 :(得分:3)
问题是两个线程都使用相同的队列。死锁场景是:
'shutdown'
t1.stop()
t2
从'shutdown'
q
t1
,它正在等待新邮件。您可以通过制作2个队列或执行前两个shutdown
消息然后两个连接来解决此问题。
答案 1 :(得分: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
中定期检查此属性。