我从 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 还大。
