【问题标题】:python thread join not happening properlypython线程连接没有正确发生
【发布时间】:2013-04-16 12:12:21
【问题描述】:
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,它会完美运行。

我想了解我在尝试使用 join 时是否存在问题。

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

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

    1. 主线程在t1.stop()中发送'shutdown'
    2. t2q 读取 'shutdown'
    3. 主线程加入t1,它一直在等待新消息。

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

    【讨论】:

    • 那么,t2.stop 会被调用吗?
    • @GodMan,它没有。主线程永远不会从t1.join() 返回,因为它永远不会结束。
    【解决方案2】:

    问题是你有两个线程使用一个队列。当您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 中定期检查此属性。

    【讨论】:

    • 但是,如果我在做 self.join,我怎么会加入错误的呢?
    • 问题不在于调用join,而在于将shutdown 放入队列中。关闭请求可能会到达错误的线程(不是self
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多