Skip to main content
 首页 » 编程设计

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

2025年05月04日27over140

我从 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() 的特殊情况?

请您参考如下方法:

I'm just wondering if there are any special cases when join() doesn't need to be used?

最明显的情况是,当某个其他线程(您正在加入)正在加入该线程时,您不必这样做,但大概您不需要被告知一。 :)

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

其次,如果您不加入您的(正常的、非守护程序的)线程,实际上并没有准确记录会发生什么。您的主线程可能会以任意顺序等待所有这些,或者它可能会退出并返回到 shell,而线程仍在后台工作,或者它可能会杀死它们。但是,如果您出于某种原因根本不关心其中的哪一个发生,那么请不要加入。

第三,在许多平台上, 明确定义了将要发生的事情(并且通常是“它们都以某种任意顺序加入”)。比方说,如果你正在编写一个只需要在 Red Hat Linux 下的 CPython 上运行的程序,并且你确定在 Red Hat Linux 下的 CPython 中会发生什么,并且你的程序结构使得很难跟踪你的线程,那么不加入它们(可能带有注释)而不是重新构建整个程序是合理的。

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