Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
父线程先于子线程退出[python]_Python_Multithreading_Smtp_Cgi - Fatal编程技术网

父线程先于子线程退出[python]

父线程先于子线程退出[python],python,multithreading,smtp,cgi,Python,Multithreading,Smtp,Cgi,我在一个webapp(用于测试的CGI,用于生产的FastCGI)中使用Python,它需要偶尔发送一封电子邮件(当用户注册或发生其他重要事件时)。由于与SMTP服务器通信需要很长时间,我想为邮件功能生成一个线程,这样应用程序的其余部分就可以在不等待电子邮件发送完成的情况下完成请求 我尝试使用thread.start_new(func,(args)),但是父级在发送完成之前返回并退出,从而在发送过程做任何有用的事情之前终止发送过程。是否仍有足够长的时间让进程保持活动状态以使子进程完成?请查看该方

我在一个webapp(用于测试的CGI,用于生产的FastCGI)中使用Python,它需要偶尔发送一封电子邮件(当用户注册或发生其他重要事件时)。由于与SMTP服务器通信需要很长时间,我想为邮件功能生成一个线程,这样应用程序的其余部分就可以在不等待电子邮件发送完成的情况下完成请求

我尝试使用
thread.start_new(func,(args))
,但是父级
在发送完成之前返回并退出,从而在发送过程做任何有用的事情之前终止发送过程。是否仍有足够长的时间让进程保持活动状态以使子进程完成?

请查看该方法。基本上,它会阻止您的调用线程,直到子线程返回(从而防止它在应该退出之前退出)

更新:

为了避免主线程对新请求没有响应,可以使用while循环

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\u new(func,args)
is。它已更新为
thread.start\u new\u thread(function,args[,kwargs])
您还可以使用更高级别的线程包(此包允许您在上一个代码块中获取
活动线程计数()
):


如果您有多个工作线程,并且希望查看哪些工作线程仍在运行,则可能需要使用threading.enumerate


其他替代方法包括使用threading.Event--主线程将事件设置为True并启动辅助线程。工作线程在if完成工作时取消设置事件,主线程检查事件是否已设置/取消设置,以确定它是否可以退出

这可能会起作用,但当作为FastCGI运行时,它不会阻止脚本处理新请求吗?我从未使用过FastCGI,但可能。你可以做的是把连接放在一个while循环中,并给它一个超时时间,这样它就可以尝试连接线程,超时并寻找新的请求。将它设置为守护进程似乎可以工作。我没有意识到
start\u new
已被弃用。谢谢如果我启动一个守护进程线程来完成一项任务,并且没有对该线程的引用,那么它会保持足够长的活动时间来完成任务,然后销毁吗?@Narcolapser“当没有活动的非守护进程线程时,整个Python程序都会退出。”只要满足这个条件,我相信线程会完成它的任务,然后销毁。对线程的所有引用都提供了一种在启动线程后与之交互的方式。请参阅此处的文档:
import threading
my_thread = threading.Thread(target=func, args=(), kwargs={})
my_thread.daemon = True
my_thread.start()