我是否应该总是使用 threading.Thread.join()?
我从这里学到了多线程的知识,并且我把最后一个例子当作我所有多线程应用的模板。下面是代码:
#!/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 个回答
9
我只是想知道有没有什么特殊情况是可以不使用 join() 的?
显而易见的情况是,当有其他线程(你要连接的那个线程)正在连接这个线程时,你就不需要再做了,不过这个你应该早就知道了。:)
首先,daemon
线程是可以不需要连接的(通常也不应该连接)。你可以直接放弃它们,它们会在你的主线程退出时突然被终止。(当然,确保在守护线程中不要做一些危险的事情,比如覆盖文件。)
其次,如果你不去 join
你的(正常的、非守护的)线程,实际上并没有明确记录会发生什么。你的主线程可能会以某种随机的顺序等待所有线程,或者它可能会在后台线程继续工作的同时退出并返回到命令行,或者它可能会杀掉这些线程。但如果你根本不在乎会发生哪种情况,那就可以不 join
。
第三,在很多平台上,发生的事情是有明确规定的(通常是“它们都会以某种随机的顺序被 join
”)。比如说,如果你正在写一个只需要在 Red Hat Linux 下的 CPython 上运行的程序,并且你确定在 Red Hat Linux 下 CPython 的行为,那么如果你的程序结构让你很难跟踪线程,直接不 join
也是合理的(可以加个注释说明一下),而不是重新设计整个程序。
最后,虚拟线程(dummy threads)是不用连接的。但如果你有虚拟线程却不知道自己有虚拟线程,那你就有比 join
更大的问题了。