在我所知道的所有实现中(C Python,PyPy和Jython),都使用OS线程来实现Python线程。对于每个Python线程,都有一个底层的OS线程。
某些 *** 作系统(Linux是其中之一)在所有正在运行的进程的列表中显示了同一可执行文件启动的所有不同线程。这是 *** 作系统的实现细节,而不是Python的实现细节。在某些其他 *** 作系统上,列出所有进程时可能看不到那些线程。
最后一个非守护线程完成时,该过程将终止。届时,所有守护程序线程将终止。因此,这些线程是您进程的一部分,但并不能阻止它终止(而常规线程可以阻止它终止)。那是用纯Python实现的。进程在
_exit
调用系统函数时终止(它将杀死所有线程),并且在主线程终止(或被sys.exit
调用)时,Python解释器检查是否有另一个非守护进程线程在运行。如果没有,则调用_exit
,否则它将等待非守护进程线程完成。
守护程序线程标志由
threading模块在纯Python中实现。加载模块时,将
Thread创建一个代表主线程的对象,并将其
_exitfunc方法注册为
atexit钩子。
该函数的代码是:
class _MainThread(Thread): def _exitfunc(self): self._Thread__stop() t = _pickSomeNonDaemonThread() if t: if __debug__: self._note("%s: waiting for other threads", self) while t: t.join() t = _pickSomeNonDaemonThread() if __debug__: self._note("%s: exiting", self) self._Thread__delete()
调用时
sys.exit或主线程终止时,Python解释器将调用此函数。当函数返回时,解释器将调用系统
_exit函数。当只有守护程序线程在运行时(如果有),该函数将终止。
_exit调用该函数时, *** 作系统将终止所有进程线程,然后终止进程。在
_exit所有非守护程序线程完成之前,Python运行时不会调用该函数。
所有线程都是该过程的一部分。
我的解释/理解是:当所有非守护程序线程终止时,主线程终止。
因此,如果“仅保留守护程序线程时整个Python程序退出”,那么python守护程序线程就不属于python程序?
您的理解不正确。对于OS,一个进程由许多线程组成,所有线程都是相同的(对于OS的主线程,没有什么特别的,除了C运行时
_exit在
main函数末尾添加了对它的调用)。而且 *** 作系统不知道守护线程。这纯粹是一个Python概念。
Python解释器使用本机线程来实现Python线程,但必须记住创建的线程列表。并使用其
atexit钩子确保
_exit仅在最后一个非守护线程终止时函数才返回 *** 作系统。当使用“整个Python程序”时,文档指的是整个过程。
以下程序可以帮助您了解守护程序线程和常规线程之间的区别:
import sysimport timeimport threadingclass WorkerThread(threading.Thread): def run(self): while True: print 'Working hard' time.sleep(0.5)def main(args): use_daemon = False for arg in args: if arg == '--use_daemon': use_daemon = True worker = WorkerThread() worker.setDaemon(use_daemon) worker.start() time.sleep(1) sys.exit(0)if __name__ == '__main__': main(sys.argv[1:])
如果使用’–use_daemon’执行该程序,您将看到该程序仅打印少量
Workinghard行。没有此标志,即使主线程完成,程序也不会终止,并且程序将打印
Working hard行直到被杀死。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)