什么时候主线程将在python中退出

时间:2014-04-25 06:31:50

标签: python multithreading

我正在阅读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中退出?

5 个答案:

答案 0 :(得分:9)

只要脚本中的所有代码都没有在单独的线程中启动,主线程就会退出。

由于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"

答案 1 :(得分:5)

根据the threading docs

  

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

这与你给出的引用一致,但是措辞的细微差别显示了你得到的结果。主要线程'当你期望它退出时退出。请注意, worker 线程此时仍在运行 - 您可以在给出的测试输出中看到这一点。所以,主线程已经完成,但整个过程仍在运行,因为还有其他线程仍在运行。

不同之处在于,如果其中一些工作线程被守护,那么当最后一个非守护程序线程完成时,它们将被强行杀死。如果所有工作人员都是守护程序线程,那么整个过程就会完成 - 并且您将在系统shell提示符后返回 - 很快就会打印出主要退出程序',并且在此之后,任何工人打印都会非常罕见(尽管并非不可能,因为竞争条件)。

答案 2 :(得分:0)

你的主线程将以soos的形式退出,因为for循环完成了它的执行。您的主线程正在启​​动新的异步线程。这意味着它不会等待,直到新线程完成其执行。所以在你的情况下,主线程将并行启动5个线程并退出。

答案 3 :(得分:0)

请注意,在您打印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总是在所有工人完成工作之后出现。

答案 4 :(得分:0)

例如如下:

    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)主要结束

当前线程为True

主线程为False

T1:提高......

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