Python:多线程复制-线程仍然存在

时间:2018-11-20 11:00:07

标签: python multithreading multiprocessing python-multithreading

您好,我的问题是我有一个多线程复制类。复制效果很好,但是该程序不会退出,因为复制后线程仍然存在。我试图建立一个线程事件,但这没有效果。 t.join()永无休止,因为线程仍然存在。我也将它们变成了守护进程,但这是不必要的,因为程序结束了,但是当程序停止时线程仍然处于活动状态。有谁知道这是怎么回事?该类的Input是一个数据框,第一列的文件源为文件,另一列的文件目标为

import shutil as sh
from multiprocessing import Queue, Process, Value, Lock, cpu_count 
import threading, os, time,queue


class ThreadedCopy():


totalFiles = 0
copyCount = 0
lock = threading.Lock()

def __init__(self,srcDst):        
    #fileList = srcDst['srcCol']
    self.fileQueue = queue.Queue()
    self.totalFiles = srcDst.shape[0]

    print(str(self.totalFiles) + " files to copy.")
    self.threadWorkerCopy(srcDst)


def CopyWorker(self):
    while True:
    #while True:
        fileRow = self.fileQueue.get()
        sh.copyfile(fileRow[1], fileRow[2])

        self.fileQueue.task_done()
        with self.lock:
            self.copyCount += 1
            percent = (self.copyCount * 100) / self.totalFiles
            if (percent%10==0):
                print(str(percent) + " percent copied.")

def threadWorkerCopy(self, srcDst):
    threads=[]
    for fileRow in srcDst.itertuples():
        self.fileQueue.put(fileRow)
    for i in range(cpu_count()):
        t = threading.Thread(target=self.CopyWorker,name='CopyThread')            
        t.daemon = True
        t.start()
        #threads.append(t)

    self.fileQueue.join()

ThreadedCopy(scrDstDf)

编辑

如果我对程序进行断码,它就挂在这里:

<ipython-input-14-8d9a9b84e73f> in threadWorkerCopy(self, srcDst)
    380         self.stop_event.set()
    381         for thread in threads:
--> 382             thread.join()
    383 
    384 #ThreadedCopy(scrDstDf)

/usr/lib/python3.5/threading.py in join(self, timeout)
   1052 
   1053         if timeout is None:
-> 1054             self._wait_for_tstate_lock()
   1055         else:
   1056             # the behavior of a negative timeout isn't documented, but

/usr/lib/python3.5/threading.py in _wait_for_tstate_lock(self, block, timeout)
   1068         if lock is None:  # already determined that the C code is done
   1069             assert self._is_stopped
-> 1070         elif lock.acquire(block, timeout):
   1071             lock.release()
   1072             self._stop()

KeyboardInterrupt: 

1 个答案:

答案 0 :(得分:1)

您的工作线程在self.fileQueue.get()上被阻止,这就是为什么它不检查stop事件。

解决此问题的最简单方法是使该线程成为守护线程。这样,当主线程终止时,它们将自动终止。

如果由于某种原因您不想/不能执行此操作,那么您需要通过在工作人员将检查的队列中插入一个特殊的标记值来唤醒工作线程,如果工作人员看到队列中的这个值,它应该终止。