2016-07-20 3 views
1

내 코드가 진행 상황 표시 줄을 표시하면서 작업을 종료 할 때 사용자가 close 버튼을 클릭하면 스레드 기능이 종료되지 않고 잠금 상태가됩니다. 메인 UI 스레드가 잠금 해제됩니다. Cancel 버튼을 클릭하면 p4.run_sync()이 종료되지 않습니다.파이썬에서 다중 프로세서 처리하기

def P4SyncLibrary(args, que): 
    syncType = args[0] 
    view = args[1] 
    p4 = P4CreateConnection(disable_tmp_cleanup=True) 
    try: 
     p4.run_sync(view) 
    except P4Exception: 
     for e in p4.errors: 
      print "SyncError: - %s" %e 
    p4.disconnect() 
    que.put(None) 


class CreateJob(QtGui.QDialog): 
    def __init__(self, thread, args): 
     QtGui.QDialog.__init__(self) 
     self.ui=Ui_ProgressBar() 
     self.ui.setupUi(self) 
     self.ui.cancel.clicked.connect(self.closeEvent) 
     self.ui.cancel.setIcon(QtGui.QIcon(QtGui.QPixmap("%s/delete.xpm" %resources))) 

     self.threadControl = ThreadControl(thread=thread, args=args) 
     self.connect(self.threadControl, QtCore.SIGNAL("__updateProgressBar(int)"), self.__updateProgressBar) 
     self.threadControl.finished.connect(self.closeEvent) 
     self.threadControl.start() 

    @QtCore.pyqtSlot(int) 
    def __updateProgressBar(self,val): 
     self.ui.progressBar.setValue(val) 
     self.setWindowTitle("Processing: {0}%".format(val)) 

    def closeEvent(self, QCloseEvent=None): 
     if self.threadControl.isRunning(): 
      self.threadControl.stop() 
      self.threadControl.wait() 
     if QCloseEvent: QtGui.QDialog.closeEvent(self, QCloseEvent) 
     else: self.close() 

    def getResults(self): 
     return self.threadControl.resultDict 

class ThreadControl(QtCore.QThread): 
    stopFlag = 0 
    def __init__(self, thread=None, args=None): 
     super(ThreadControl, self).__init__() 
     self.args = args 
     self.thread = thread 
     self.resultDict = [] 

    def run(self): 
     threads = {} 
     queue = multiprocessing.Queue() 
     for arg in self.args: 
      process = multiprocessing.Process(target=self.thread, args=(arg, queue)) 
      process.start() 
      threads[process] = 1 ## ACTIVE thread 

     # WAIT TILL ALL PROCESSES COMPLETE 
     completedThreads = 0 
     total = len(threads.keys()) 
     while completedThreads != total: 
      if self.stopFlag: 
       for t in threads.keys(): 
        if threads[t] == 1: 
         t.terminate() 
         t.join() 
         threads[t] = 0 
         completedThreads += 1 
      else: 
       for t in threads.keys(): 
        if self.stopFlag: break ## Process threads termination 
        elif threads[t] == 1 and not t.is_alive(): 
         threads[t] = 0 
         completedThreads += 1 
         self.resultDict.append(queue.get()) 
      self.emit(QtCore.SIGNAL('__updateProgressBar(int)'),(completedThreads*100)/total) 
      sleep(0.5) ## Prevent CPU from overloading 

    def stop(self): 
     self.stopFlag=1 

작업이 CreateJob

내가 줄 수있는 유일한 해결책은 사용자가 원할 때 그 P4 서버 연결을 해제 할 수 있도록 인수로 스레드를 호출하는 P4 객체를 전달하는 것입니다
CreateJob(thread=P4SyncLibrary, args=P4Libraries).exec_() 

답변

0

의 인스턴스를 사용하여 생성되는 작업을 취소하십시오.

def P4SyncLibrary(p4, args, que): 
    syncType = args[0] 
    view = args[1] 
    try: 
     p4.run_sync(view) 
    except P4Exception: 
     for e in p4.errors: 
      print "SyncError: - %s" %e 
    que.put(None) 

class ThreadControl(QtCore.QThread): 

    ... 

    def run(self): 
     threads = {} 
     queue = multiprocessing.Queue() 
     for arg in self.args: 
      connection = P4CreateConnection(disable_tmp_cleanup=True) 
      if connection.connected(): 
       process = multiprocessing.Process(target=self.thread, args=(connection, arg, queue)) 
       process.start() 
       threads[process] = { 
        'isAlive': True, 
        'connection': connection 
       } 

     # WAIT TILL ALL PROCESSES COMPLETE 
     completedThreads = 0 
     total = len(threads.keys()) 
     while completedThreads != total: 
      if self._stop: 
       for t in threads.keys(): 
        if threads[t]['isAlive']: 
         threads[t]['connection'].disconnect() 
         t.terminate() 
         t.join() 

         threads[t]['isAlive'] = False 
         completedThreads += 1 
      else: 
       for t in threads.keys(): 
        if self._stop: break ## Process threads termination 
        elif threads[t]['isAlive'] and not t.is_alive(): 
         threads[t]['connection'].disconnect() 
         threads[t]['isAlive'] = False 
         completedThreads += 1 
         self.results.append(queue.get()) 
      self.emit(QtCore.SIGNAL('__updateProgressBar(int)'),(completedThreads*100)/total) 
      sleep(0.5) ## Prevent CPU from overloading 
관련 문제