父线程在子线程前退出 [python]

2 投票
2 回答
4244 浏览
提问于 2025-04-15 22:48

我在一个网页应用中使用Python(测试时用CGI,生产时用FastCGI),这个应用需要偶尔发送邮件,比如用户注册时或者发生其他重要事情时。因为和SMTP服务器通信比较慢,我想为发送邮件的功能开一个新线程,这样应用的其他部分就可以继续处理请求,而不用等邮件发送完。

我试过用thread.start_new(func, (args))来实现,但父线程在发送完成之前就已经return并退出了,这样就把发送邮件的过程给中断了,导致它无法完成任何有用的工作。有没有办法让这个过程活得久一点,以便子线程能完成它的工作呢?

2 个回答

0

如果你有多个工作线程,并且想知道哪些线程还在运行,可以考虑使用 threading.enumerate。

另外一种方法是使用 threading.Event——主线程把事件设置为 True,然后启动工作线程。工作线程完成工作后会把事件设置为 False,主线程可以检查这个事件是设置还是未设置,从而判断自己是否可以退出。

3

看看这个 thread.join() 方法。简单来说,它会让你调用的线程停下来,直到子线程完成工作(这样可以防止主线程在子线程还没结束时就退出)。

更新:

为了避免让你的主线程对新请求没有反应,你可以使用一个循环。

while threading.active_count() > 0:
    # ... look for new requests to handle ...
    time.sleep(0.1)  

    # or try joining your threads with a timeout
    #for thread in my_threads:
    #    thread.join(0.1)        

更新 2:

看起来 thread.start_new(func, args) 已经 过时 了。它已经更新为 thread.start_new_thread(function, args[, kwargs])。你也可以使用更高级的线程包来创建线程(这个包可以让你获取到之前代码块中的 active_count()):

import threading
my_thread = threading.Thread(target=func, args=(), kwargs={})
my_thread.daemon = True
my_thread.start()

撰写回答