简体   繁体   English

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

[英]when will main thread exit in python

I am reading The Python Standard Library by Example and get confused when I arrived page 509. 我正在The Python Standard Library by Example阅读The Python Standard Library by Example当我到达第509页时感到困惑。

Up to this point, the example programs have implicitly waited to exit until all threads have completed their work. 到目前为止,示例程序已隐式等待退出,直到所有线程完成其工作。 Programs sometimes spawn a thread as a daemon that runs without blocking the main program from exiting. 程序有时会产生一个线程作为守护进程,它可以在不阻止主程序退出的情况下运行。

but after I run some codes, I get result that is opposite. 但是在我运行一些代码之后,我得到了相反的结果。 The code is like this: 代码是这样的:

    #!/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"

and sometime the result is this: 有时结果如下:

Worker
Worker
WorkerWorker

main Exit
Worker

So I want to ask when will main thread exit in python after it starts several thread? 所以我想问一下,在启动多个线程后,主线程何时会在python中退出?

The main thread will exit whenever it is finished executing all the code in your script that is not started in a separate thread. 只要完成执行脚本中未在单独线程中启动的所有代码,主线程就会退出。

Since the t.start() will start the thread and then return to the main thread, the main thread will simply continue to execute until it reaches the bottom of your script and then exit. 由于t.start()将启动线程然后返回主线程,主线程将继续执行,直到它到达脚本的底部然后退出。

Since you started the other threads in a non-daemon mode, they will continue running until they are finished. 由于您以非守护进程模式启动了其他线程,因此它们将继续运行直到完成。

If you wanted the main thread to not exit until all the threads have finished, you should explicitly join them to the main thread. 如果您希望主线程在所有线程完成之前不退出,则应join它们显式join到主线程。 The join will cause the thread calling join to wait until the the thread being joined is finished. join将导致线程调用join等待,直到加入的线程完成。

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

As @codesparkle pointed out, the more Pythonic way to write this would be to skip the index variable entirely. 正如@codesparkle指出的那样,Pythonic写这个的方式就是完全跳过索引变量。

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

According to the threading docs : 根据线程文档

The entire Python program exits when only daemon threads are left 当只剩下守护程序线程时,整个Python程序退出

This agrees with the quote you give, but the slight difference in wording shows the result you get. 这与你给出的引用一致,但是措辞的细微差别显示了你得到的结果。 The 'main thread' exits when you would expect it to. 当您期望它时,'主线程'退出。 Note that the worker threads keep running at this point - you can see this in the test output you give. 请注意,此时工作线程仍在运行 - 您可以在给出的测试输出中看到这一点。 So, the main thread has finished, but the whole process is still running because there are other threads still running. 因此,主线程已经完成,但整个过程仍在运行,因为还有其他线程仍在运行。

The difference is that if some of those worker threads were daemonised, they would be forcibly killed when the last non-daemon thread finished. 不同之处在于,如果其中一些工作线程被守护,那么当最后一个非守护程序线程完成时,它们将被强行杀死。 If all of the workers were daemon threads, then the entire process would finish - and you would be back at your systems shell prompt - very soon after you print 'main exit', and it would be very rare (though not impossible, owing to race conditions) for any worker to print after that. 如果所有的工作程序都是守护程序线程,那么整个过程就会完成 - 你会在打印“主要出口”之后很快回到你的系统shell提示符,这将是非常罕见的(尽管并非不可能,因为竞争条件)任何工人在此之后进行印刷。

Your main thread will exit as soos as for loop completes its execution. 您的主线程将作为soos退出,因为for循环完成其执行。 Your main thread is starting new asynchronous threads. 您的主线程正在启​​动新的异步线程。 Which means that it will not wait untill new thread finishes its execution. 这意味着它不会等待,直到新线程完成其执行。 So in your case main thread will start 5 threads in parallel and exit itself. 所以在你的情况下,主线程将并行启动5个线程并退出自己。

Note that Main does not exit when you print main Exit , but after it. 请注意,当您打印main Exit时,Main不会main Exit ,但在此之后。 Consider this program: 考虑这个程序:

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"

I have created an object whose sole purpose is to print "I am dying" when it is being finalised. 我创建了一个对象,其唯一目的是在最终确定时打印“我正在死去”。 I am not deleting it explicitly anywhere, so it will only die when the main thread finishes, that is, when Python starts to kill everything to return memory to the OS. 我没有在任何地方明确地删除它,所以它只会在主线程完成时死掉,也就是说,当Python开始杀死所有内容以将内存返回给操作系统时。

If you run this you will see that workers are working when the main thread is done, but the objects are still alive. 如果你运行它,你会看到工作人员在主线程完成时工作,但对象仍然存在。 I am dying always comes after all the workers have finished their job. 在所有工人完成工作后, I am dying了。

For example as follow: 例如如下:

    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: sleeping... > T1:睡觉......

(MainThread) main end (MainThread)主要结束

current thread is True 当前线程为True

main thread is False 主线程为False

T1: raising... T1:提高......

you can see the main thread active state is false? 你可以看到主线程的活动状态是假的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM