Python版本:'2.7.3(默认,2013年4月10日,06:20:15)\ n [GCC 4.6.3]'
我有这个:
#!/usr/bin/env python
import time, threading, os
def f1(arg1):
for i in xrange(arg1):
time.sleep(1)
print "i is: ", i
print threading.active_count()
print threading.enumerate()
if __name__ == '__main__':
t = threading.Thread(name="MyThread1", target=f1, args=(5,))
t.start()
我的问题是,为什么活动线程的数量被报告为2,为什么enumerate
生成的列表也包含主线程。
我认为主线程在产生“MyThread1”之后终止。
$ ./threadeg.py
i is: 0
2
[<_MainThread(MainThread, stopped 139858183157504)>, <Thread(MyThread1, started 139858153768704)>]
i is: 1
2
[<_MainThread(MainThread, stopped 139858183157504)>, <Thread(MyThread1, started 139858153768704)>]
i is: 2
2
[<_MainThread(MainThread, stopped 139858183157504)>, <Thread(MyThread1, started 139858153768704)>]
i is: 3
2
[<_MainThread(MainThread, stopped 139858183157504)>, <Thread(MyThread1, started 139858153768704)>]
i is: 4
2
[<_MainThread(MainThread, stopped 139858183157504)>, <Thread(MyThread1, started 139858153768704)>]
答案 0 :(得分:1)
threading.activeCount(),返回活动的线程数 (那是从那个模块开始的)。 [Source]
由于线程模块是一个构建在线程模块之上的纯python模块,因此查看源代码非常容易。
以下是active_count
def activeCount():
"""Return the number of Thread objects currently alive.
The returned count is equal to the length of the list returned by
enumerate().
"""
with _active_limbo_lock:
return len(_active) + len(_limbo)
经过进一步调查后,应该注意到_MainThread实例存储在_active中(_active和_limbo都是将线程名称映射到其实例的字典)。并且在调用_exitfunc
时从_active中删除。
以下是_MainThread的来源,
class _MainThread(Thread):
def __init__(self):
Thread.__init__(self, name="MainThread")
self._Thread__started.set()
self._set_ident()
with _active_limbo_lock:
_active[_get_ident()] = self
def _set_daemon(self):
return False
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()
调用_exitfunc
_MainThread
等待所有非守护程序线程加入,然后调用Thread._delete
,在这种情况下mangled __Thread_delete
到_MainThread
反过来从_active
词典中删除_exitfunc
。
_shutdown
已在第1201行分配给_shutdown = _MainThread()._exitfunc
。
_shutdown
Py_Finalize
来自pythonrun.c,后者由Py_Finalize
调用。 Py_Exit调用import threading, time
def f():
time.sleep(1) #wait for the interpreter to "shutdown"
print threading.enumerate()
if __name__ == '__main__':
t = threading.Thread(target=f)
t.daemon = True
t.start()
threading._shutdown() #simulate an interpreter shutdown
,它退出主进程(此时只剩下守护进程)。
退出当前进程。这将调用Py_Finalize(),然后调用标准C库函数exit(status)。
这是一个让您了解所期望行为的示例。
{{1}}
另一个很好的answer描述了线程是如何关闭的。