活动线程数

时间:2014-02-09 00:22:39

标签: python multithreading

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)>]

1 个答案:

答案 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_Exit's documentation

  

退出当前进程。这将调用Py_Finalize(),然后调用标准C库函数exit(status)。

这是一个让您了解所期望行为的示例。

{{1}}

另一个很好的answer描述了线程是如何关闭的。