我应该总是使用threading.Thread.join()

时间:2014-08-08 01:14:36

标签: python multithreading

我从here学习了多线程,我使用最后一个示例作为所有多线程应用程序的模板。这是代码:

#!/usr/bin/python

import Queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data)
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# Fill the queue
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Wait for queue to empty
while not workQueue.empty():
    pass

# Notify threads it's time to exit
exitFlag = 1

#here is where i do my write to file, the last operation**

# Wait for all threads to complete
for t in threads:
    t.join()
#print "Exiting Main Thread"

如您所见,此示例在所有线程上使用t.join()来等待它们完成。我的实际版本是超长和大项目,但这不是重点。我只是想知道在join()不需要使用时是否有任何特殊情况?

1 个答案:

答案 0 :(得分:6)

  

我只是想知道在不需要使用join()时是否有任何特殊情况?

显而易见的情况是,某些其他主题(您正在加入)正在加入主题,因此您不必这样做,但可能您没有需要被告知那一个。 :)

首先,daemon线程不需要连接(通常不应该)。您可以放弃它们,当主线程退出时,它们会在某个时刻突然终止。 (当然,确保不要在守护程序线程中做任何危险的事情,比如覆盖文件。)

其次,如果你没有join你的(正常的,非守护进程)线程,那么它实际上并没有准确记录会发生什么。你的主线程可能以任意顺序等待所有这些,或者当线程在后台继续工作时它可能退出并返回shell,或者它可能会杀死它们。但如果你出于某些原因不关心其中一个发生的事情,那就不要join

第三,在许多平台上, 很好地定义了将要发生的事情(通常情况下,它们会以某种任意顺序获得join#&#34} 34)。比方说,如果您正在编写一个只需要在Red Hat Linux下运行CPython的程序,而且您确定在Red Hat Linux下CPython中会发生什么,并且您的程序结构很难保持跟踪你的主题,然后只是join他们(可能有评论)而不是重新架构你的整个程序是合理的。

最后,虚拟线程不应该加入。但是如果你有虚拟线程并且不知道你有虚拟线程,那么你遇到的问题比join更大。