1

multiprocessing.Pool을 사용하고 싶지만, multiprocessing.Pool이 타임 아웃 후에 작업을 중단 할 수 없습니다. 나는 solution을 발견하고 일부는 그것을 수정합니다.파이썬 다중 처리 풀 타임 아웃

from multiprocessing import util, Pool, TimeoutError 
from multiprocessing.dummy import Pool as ThreadPool 
import threading 
import sys 
from functools import partial 
import time 


def worker(y): 
    print("worker sleep {} sec, thread: {}".format(y, threading.current_thread())) 
    start = time.time() 
    while True: 
     if time.time() - start >= y: 
      break 
     time.sleep(0.5) 
     # show work progress 
     print(y) 
    return y 


def collect_my_result(result): 
    print("Got result {}".format(result)) 


def abortable_worker(func, *args, **kwargs): 
    timeout = kwargs.get('timeout', None) 
    p = ThreadPool(1) 
    res = p.apply_async(func, args=args) 
    try: 
     # Wait timeout seconds for func to complete. 
     out = res.get(timeout) 
    except TimeoutError: 
     print("Aborting due to timeout {}".format(args[1])) 
     # kill worker itself when get TimeoutError 
     sys.exit(1) 
    else: 
     return out 


def empty_func(): 
    pass 


if __name__ == "__main__": 
    TIMEOUT = 4 
    util.log_to_stderr(util.DEBUG) 
    pool = Pool(processes=4) 

    # k - time to job sleep 
    featureClass = [(k,) for k in range(20, 0, -1)] # list of arguments 
    for f in featureClass: 
     # check available worker 
     pool.apply(empty_func) 

     # run job with timeout 
     abortable_func = partial(abortable_worker, worker, timeout=TIMEOUT) 
     pool.apply_async(abortable_func, args=f, callback=collect_my_result) 

    time.sleep(TIMEOUT) 
    pool.terminate() 
    print("exit") 

주요 수정 - sys.exit (1)와 작업자 프로세스 종료. 그것은 작업자 프로세스를 죽이고 작업 스레드를 죽일거야,하지만 난이 솔루션이 좋다는 것을 모르겠다. 프로세스가 실행중인 작업으로 종료 될 때 발생할 수있는 잠재적 인 문제점은 무엇입니까?

+0

당신의 작업자()에서 시간 초과를 처리하고 그 결과를 공통 콜렉션에 써주는 것이 좋을 것 같습니다. 이 방법으로 모든 스레드에서 join()을 호출 한 다음 결과를 처리하면됩니다. 시스템에 과부하가 걸리지 않으면 모든 것이 제대로 작동해야합니다. – mljli

답변

4

실행중인 작업을 중지 할 때 암시적인 위험이 없으므로 OS가 프로세스를 올바르게 종료합니다.

작업이 파일에 쓰는 경우 디스크에 많은 파일이 잘릴 수 있습니다.

DB에 글을 쓰거나 일부 원격 프로세스에 연결된 경우에도 약간의 문제가 발생할 수 있습니다.

그럼에도 불구하고 Python 표준 풀은 시간 초과를 지원하지 않으며 프로세스를 갑자기 종료하면 응용 프로그램 내에서 이상한 동작이 발생할 수 있습니다.

Pebble 처리 풀은 시간 초과 작업을 지원합니다.

from pebble import process, TimeoutError 

with process.Pool() as pool: 
    task = pool.schedule(function, args=[1,2], timeout=5) 

    try: 
     result = task.get() 
    except TimeoutError: 
     print "Task: %s took more than 5 seconds to complete" % task 
+0

괜찮아 보이는군요. 실전에서 성공 사례를 사용하고 있습니까? – rusnasonov

+0

잘 모르겠습니다. 생산 또는 시스템 킬링 프로세스에서 페블의 성공 사례를 원하십니까? 페블은 공정한 [다운로드 양]의 매우 안정된 라이브러리입니다 (http://pypi-ranking.info/module/Pebble). – noxdafox

+0

예, 올바르게 이해하고 있습니다. 당신은 peeble을 사용하는 프로젝트를 알고 있습니까? – rusnasonov