<p>你的例子有两个主要问题。在</p>
<p>首先,发出信号的对象是在main/gui线程中创建的,因此它发出的任何信号都不会是跨线程的,因此不是线程安全的。显而易见的解决方案是在工作线程的目标函数内部创建信令对象,这意味着每个线程都必须有一个单独的实例。在</p>
<p>其次,目标函数中的while循环永远不会终止,这意味着在当前复制操作完成后,每个<code>ThreadedCopy</code>对象都将保持活动状态。由于所有这些对象共享同一个队列,如果试图重复复制操作,行为将变得不可预测。显而易见的解决方案是,一旦队列为空,就跳出while循环。在</p>
<p>下面是对MultithreadedCopy_5.py</em>的重写,应该可以解决这些问题。但是,正如评论中所述,我仍然强烈建议在这个场景中使用<code>QThread</code>而不是python线程,因为它可能提供一个更健壮、更易于维护的解决方案。在</p>
<pre><code>import Queue, threading
from PyQt4 import QtCore
import shutil
import profile
fileQueue = Queue.Queue()
class Communicate(QtCore.QObject):
progressSignal = QtCore.pyqtSignal(int)
class ThreadedCopy:
totalFiles = 0
copyCount = 0
lock = threading.Lock()
def __init__(self, inputList, progressBar="Undefined"):
self.progressBar = progressBar
self.totalFiles = len(inputList)
print str(self.totalFiles) + " files to copy."
self.threadWorkerCopy(inputList)
def CopyWorker(self):
c = Communicate()
c.progressSignal.connect(self.updateProgressBar)
while True:
try:
fileName = fileQueue.get(False)
except Queue.Empty:
break
else:
shutil.copy(fileName[0], fileName[1])
with self.lock:
self.copyCount += 1
percent = (self.copyCount * 100) / self.totalFiles
c.progressSignal.emit(percent)
fileQueue.task_done()
def threadWorkerCopy(self, fileNameList):
if fileQueue.empty():
for i in range(16):
t = threading.Thread(target=self.CopyWorker)
t.daemon = True
t.start()
for fileName in fileNameList:
fileQueue.put(fileName)
fileQueue.join()
def updateProgressBar(self, percent):
self.progressBar.setValue(percent)
</code></pre>