【问题标题】:when will main thread exit in pythonpython主线程什么时候退出
【发布时间】:2014-06-10 17:34:57
【问题描述】:

我正在阅读The Python Standard Library by Example,当我到达第 509 页时感到困惑。

到目前为止,示例程序已隐式等待退出,直到所有线程完成其工作。程序有时会生成一个线程作为守护进程,该线程在不阻止主程序退出的情况下运行。

但是在我运行一些代码之后,我得到了相反的结果。代码是这样的:

    #!/usr/bin/env python
# encoding: utf-8
#
# Copyright (c) 2008 Doug Hellmann All rights reserved.
#
"""Creating and waiting for a thread.
"""
#end_pymotw_header

import threading
import time

def worker():
    """thread worker function"""
    print 'Worker'
    # time.sleep(10000)
    return

threads = []
for i in range(5):
    t = threading.Thread(target=worker)
    threads.append(t)
    t.start()

print "main Exit"

有时结果是这样的:

Worker
Worker
WorkerWorker

main Exit
Worker

所以我想问一下python中的主线程启动几个线程后什么时候退出?

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    例如如下:

        class ThreadA(Thread):
            def __init__(self, mt):
                Thread.__init__(self)
                self.mt = mt
    
            def run(self):
                print 'T1: sleeping...'
                time.sleep(4)
                print 'current thread is ', self.isAlive()
                print 'main thread is ', self.mt.isAlive()
                print 'T1: raising...'
    
    if __name__ == '__main__':
        mt = threading.currentThread()
        ta = ThreadA(mt)
        ta.start()
        logging.debug('main end')
    

    > T1:睡觉……

    (MainThread) 主端

    当前线程为真

    主线程是假的

    T1:加注……

    你可以看到主线程活动状态是假的吗?

    【讨论】:

      【解决方案2】:

      请注意,当您打印main Exit 时,Main 不会退出,而是在它之后。考虑这个程序:

      import threading
      import time
      
      def worker():
          """thread worker function"""
          print 'Worker'
          time.sleep(1)
          print 'Done'
          return
      
      
      class Exiter(object):
          def __init__(self):
              self.a = 5.0
              print 'I am alive'
          def __del__(self):
              print 'I am dying'
      
      exiter = Exiter()
      
      threads = []
      for i in range(5):
          t = threading.Thread(target=worker)
          threads.append(t)
          t.start()
      
      print "main Exit"
      

      我创建了一个对象,其唯一目的是在完成时打印“我要死了”。我没有在任何地方显式删除它,所以它只会在主线程完成时死掉,也就是说,当 Python 开始杀死所有东西以将内存返回给操作系统时。

      如果你运行它,你会看到当主线程完成时工作人员正在工作,但对象仍然活着。 I am dying 总是在所有工人完成工作之后出现。

      【讨论】:

        【解决方案3】:

        主线程将在执行完脚本中未在单独线程中启动的所有代码后退出。

        由于t.start() 将启动线程然后返回主线程,因此主线程将继续执行,直到到达脚本底部然后退出。

        由于您在非守护程序模式下启动了其他线程,它们将继续运行直到完成。

        如果您希望主线程在所有线程完成之前不退出,您应该将它们显式地join 发送到主线程。 join 将导致调用join 的线程等待,直到正在加入的线程完成。

        for i in range(5):
            threads[i].join()
        print "main Exit"
        

        正如@codesparkle 所指出的,更 Pythonic 的编写方式是完全跳过索引变量。

        for thread in threads:
            thread.join()
        print "main Exit"
        

        【讨论】:

        • @codesparkle,将更新它。我这样写是为了更贴近他已有的代码。
        【解决方案4】:

        根据the threading docs

        当只剩下守护线程时,整个 Python 程序退出

        这与您给出的报价一致,但措辞上的细微差别表明了您得到的结果。 “主线程”会在您期望的时候退出。请注意,此时 worker 线程继续运行 - 您可以在您提供的测试输出中看到这一点。所以,主线程已经完成,但整个进程仍在运行,因为还有其他线程仍在运行。

        不同之处在于,如果其中一些工作线程被守护,它们将在最后一个非守护线程完成时被强制终止。如果所有工作线程都是守护线程,那么整个过程将完成 - 您将返回系统 shell 提示符 - 在您打印 'main exit' 后不久,这将非常罕见(尽管并非不可能,由于竞争条件)之后任何工人都可以打印。

        【讨论】:

        • 我相信关键是即使当主线程退出时,程序仍然与非守护子线程一起运行。您可以通过子项中的此表达式来验证这一点:main_thread().is_alive()
        【解决方案5】:

        您的主线程将在 for 循环完成执行时退出。您的主线程正在启​​动新的异步线程。这意味着它不会等到新线程完成执行。因此,在您的情况下,主线程将并行启动 5 个线程并自行退出。

        【讨论】:

        • 不正确。主线程继续执行,但在所有子线程完成之前不会退出,如文档所述。
        • 主线程将退出,但进程不会..它是如何不正确的?
        猜你喜欢
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 2018-09-11
        • 1970-01-01
        相关资源
        最近更新 更多