当没有.join()时,python中的线程会发生什么?

时间:2018-03-06 15:20:23

标签: multithreading python-2.7

假设我们有一个多线程Python代码,如下所示:

import threading
import time

def short_task():
    print 'Hey!'

for x in range(10000):
    t = threading.Thread(target=short_task)
    t.daemon = True  # All non-daemon threads will be ".join()"'ed when main thread dies, so we mark this one as daemon
    t.start()

time.sleep(100)

在长时间运行的应用程序中使用类似的方法是否有任何副作用(例如Django + uwsgi)?就像没有垃圾收集,额外的内存消耗等?

我要做的是在不阻塞主线程的情况下进行一些代价高昂的日志记录(urlopen()到外部API网址)。产生没有.join()的无限新线程看起来像这里最好的方法,但也许我错了?

1 个答案:

答案 0 :(得分:1)

不是100%自信的答案,但因为其他人没有权衡......

我无法在Python文档中找到任何表明您必须加入线程的地方。 Python的线程模型对我来说就像Java一样:在Java中t.join()意味着"等待t死亡,"但这并不意味着什么。特别是,t.join()对线程t没有任何作用。

我不是专家,但在Python中看起来也是如此。

  

是否有任何副作用......比如...额外的内存消耗

每个Python线程都必须有自己的固定大小的调用堆栈,threading模块文档说堆栈的最小大小为32K字节。如果你创建了一万个,就像你的代码片段一样,如果它们都设置在同一时间存在,那么仅仅堆栈就会占用320兆字节的实内存。

找到一个程序有很多同时线程的充分理由是不寻常的。

如果您期望这些线程如此快速地死亡以至于其中只有少数几个同时存在,那么您可能可以通过使用{{{}来提高程序的性能。 3}}。线程池是管理少量工作线程的对象和任务的阻塞队列(即功能对象)。每个工作人员都处于循环中,从队列中挑选任务并执行它们。

一个有效使用线程池的程序重新使用其工作线程,而不是不断让线程死掉并创建新线程来替换它们。