2014-01-12 1 views
1

PyQt4와 파이썬 2.7는 작업

실행 긴에서 QThread 및 multiprocessing.pool 프로세스를 종료 차라리 대규모 데이터 세트의 처리를 관리하는 GUI 응용 프로그램이 있습니다. 이러한 데이터 세트/파일을 찾아서 함께 처리 할 파일 모음으로 그룹화 한 다음 변환 및 처리합니다. 도중에있는 각 단계는 코드에서도 분리되어 있습니다. 아이디어는 각 '단계'를 개별적으로 멈추고 시작할 수있게하는 것입니다.

기본적으로 변환/처리 단계의 줄에 정보를 입력하기 위해 큐를 사용하여 시작 부분이 매우 잘 작동하도록했습니다. 지금 내가 겪고있는 문제는 그들을 멈추게하는 것입니다 ...

저는 제가하려고하는 것에 대한 아주 작은 예를 가지고 있습니다. 그러나 본질적으로, 관련 항목 그룹을 수락하는 QThread을 시작하면 QThread은 매우 오랜 실행 프로세스 인 작업자에게 multiprocessing.pool.map을 통해 명령합니다. 처리가 20 분이 걸릴 수 있다는 것을 의미하는 매우 오랜 기간의 실행이지만 풀의 모든 프로세스를 즉시 중지 할 수 있기를 원합니다. 여기 while 루프를 사용했습니다. 전체 코드는 SubProcess을 사용하는 외부 exe 호출입니다.

장기 실행 작업이 작업자 내부에서 실행되면 강제로 강제 종료 방법을 찾을 수 없습니다 .... PyCharm의 '중지'버튼을 제대로 눌러도 강제 종료 할 수 있음에도 불구하고. 나는 여기에 어떤 변수도 공유하고 있지 않다. 그리고 현재 '작업중 인'항목이 손상되면 다음 번에 실행될 때 교체 될 것이기 때문에 걱정하지 않는다.

작업자를 어떻게 정지시킬 수 있습니까?

from multiprocessing import Queue, Pool 
from PyQt4.QtCore import * 
import time 
from itertools import repeat 


#Worker that actually does the long work task 
#Just printing in a while loop here 
def worker(ID): 
    while 1: 
     print "Hello World from ", ID 
     time.sleep(1) 
    else: 
     return 

#QThread which manages the workers 
#MyThread gets collection of tasks to perform and then sends work out to pool of workers 
#Planning for at least 3 of these to be running simultaneously in full blown script 
class MyThread(QThread): 
    def __init__(self, inqueue, outqueue, id): 
     super(MyThread, self).__init__() 
     self.inqueue = inqueue 
     self.outqueue = outqueue 
     self.ID = id 
     print 'initializedL: ', self.ID 

    def run(self): 

     while 1: 
      print "Waiting" 
      obj = self.inqueue.get(block=True) 
      self.pool = Pool(processes=6) 
      self.res = self.pool.map(worker, zip(obj, repeat(self.ID))) 
      self.pool.close() 
      self.pool.join() 

    def stop(self): 
     self.terminate() 

if __name__ == "__main__": 

    inqueue = Queue() 
    outqueue = Queue() 

    #start a new QThread which immediately waits for work to be assigned to it 
    t = MyThread(inqueue, outqueue, 1) 
    t.start() 

    time.sleep(2) 

    #Provide the QThread with a collection of items for the worker to process 
    inqueue.put([1, 2, 3, 4, 5, 6, 7, 8]) 

    time.sleep(5) 

    #At some point, I want to be able to completely dead stop all processes and threads 
    #associated with MyThread...again will be 3 MyThreads in full version 
    t.stop() 

    db=2 
    #SET DEBUG BREAKPOINT HERE TO SEE LOOP CONTINUE TO RUN 

답변

1

메서드에서 self.pool.terminate에 대한 호출을 추가하십시오. 설명서에 따르면 Pool.terminate 함수는 작업자 프로세스를 즉시 중지합니다.

+0

감사합니다. @ mguijarr, 나는 그것을 발견 했어야합니다. BTW, 철저히하기 위해, 내 실제 노동자는 오랫동안'subprocess.Popen' 호출이며,'pool()'에 대한 리턴을 기다리는 동안 대기열과 루프를 삽입했습니다. 나는 독약에 대한 큐를 확인합니다. 이 경우에는 미친 짓이 복잡해졌지만,'pool.terminate()'가 꼭 필요한 첫 걸음이었습니다! – catwalker333