2014-11-01 3 views
5

파이썬 멀티 프로세싱 풀 모듈을 사용하여 프로세스 풀을 생성하고 작업을 할당합니다.파이썬 멀티 프로세싱 프로세스 번호

나는 4 개 프로세스를 생성하고이 작업을 할당하지만, 자신의 프로세스 번호를 표시하려고하지만, 디스플레이에 난 그냥 하나 개의 프로세스 번호 "6952"을 참조하십시오이 ...되지는 2 개 프로세스 번호를 인쇄해야

from multiprocessing import Pool 
from time import sleep 

def f(x): 
    import os 
    print "process id = " , os.getpid() 
    return x*x 

if __name__ == '__main__': 
    pool = Pool(processes=4)    # start 4 worker processes 

    result = pool.map_async(f, (11,)) #Start job 1 
    result1 = pool.map_async(f, (10,)) #Start job 2 
    print "result = ", result.get(timeout=1) 
    print "result1 = ", result1.get(timeout=1) 

검색 결과 : -

result = process id = 6952 
process id = 6952 
[121] 
result1 = [100] 
+0

하는 Windows를 사용하고 있습니까? – dano

+0

@ dano-yes ....., – user1050619

답변

2

타이밍이 늦어졌습니다. Windows는 Pool에 4 개의 프로세스를 생성해야하는데,이 프로세스는 시작, 초기화 및 Queue에서 사용할 준비가 필요합니다. Windows에서이 작업을 수행하려면 각 하위 프로세스에서 __main__ 모듈을 다시 가져와야하며 에 의해 내부적으로 사용되는 Queue 인스턴스가 각 자식에서 언 패킹되어야합니다. 이것은 의미심장 한 시간을 필요로합니다. 실제로는 map_async() 호출이 모두 실행되어 Pool의 모든 프로세스가 실행되고 실행될 때까지 충분히 길다. 당신이 각 직원에 의해 운영되는 일부 추적 기능을 추가 할 경우이 작업을 볼 수 Pool :

while maxtasks is None or (maxtasks and completed < maxtasks): 
    try: 
     print("getting {}".format(current_process())) 
     task = get() # This is getting the task from the parent process 
     print("got {}".format(current_process())) 

출력 :

getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5145 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5145 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
result = [121] 
result1 = [100] 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 

는 당신이 Worker-1 시작,보고 노동자 전에 두 작업을 소모 수 있듯이 2-4 번도 Queue에서 소비하려고합니다.

getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
# <sleeping here> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5183 
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
process id = 5184 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
result = [121] 
result1 = [100] 
got <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 

가 (당신이 볼 수있는 여분의 "getting/"got" 문이라는 것을 참고 : 주요 과정에서 Pool를 인스턴스화 한 후에 만 ​​map_async를 호출하기 전에 sleep 호출을 추가하면 다른 프로세스가 각 요청을 처리 할 볼 수 있습니다 감시단은 각 프로세스로 보내져 정상적으로 종료됩니다.)

Linux에서 Python 3.x를 사용하면 'spawn''forkserver' 컨텍스트를 사용하여이 동작을 재현 할 수 있지만 'fork'은 사용할 수 없습니다. 아마도 자식 프로세스를 포크하는 것이 더럽기 때문에 __main__을 다시 가져 오는 것보다 훨씬 빠릅니다.

0

2 개의 프로세스 ID를 인쇄합니다.

result = process id = 6952 <=== process id = 6952 
process id = 6952 <=== process id = 6952 
[121] 
result1 = [100] 

이것은 작업자 프로세스가 빨리 완료되고 다른 요청을 처리 할 준비가 되었기 때문입니다.

result = pool.map_async(f, (11,)) #Start job 1 
result1 = pool.map_async(f, (10,)) #Start job 2 

위의 코드에서 작업자가 작업을 완료하고 풀로 돌아와 작업 2를 완료 할 준비가되었습니다. 이는 여러 가지 이유로 발생할 수 있습니다. 가장 빈번한 것은 노동자가 바쁘거나 준비가되어 있지 않다는 것입니다.

여기에 우리는 4 명의 근로자가있을 예정이지만 그 중 하나만 준비가 될 것입니다. 따라서 우리는 어느 것이 그 일을 할 것인지를 압니다.

# https://gist.github.com/dnozay/b2462798ca89fbbf0bf4 

from multiprocessing import Pool,Queue 
from time import sleep 

def f(x): 
    import os 
    print "process id = " , os.getpid() 
    return x*x 

# Queue that will hold amount of time to sleep 
# for each worker in the initialization 
sleeptimes = Queue() 
for times in [2,3,0,2]: 
    sleeptimes.put(times) 

# each worker will do the following init. 
# before they are handed any task. 
# in our case the 3rd worker won't sleep 
# and get all the work. 
def slowstart(q): 
    import os 
    num = q.get() 
    print "slowstart: process id = {0} (sleep({1}))".format(os.getpid(),num) 
    sleep(num) 

if __name__ == '__main__': 
    pool = Pool(processes=4,initializer=slowstart,initargs=(sleeptimes,)) # start 4 worker processes 
    result = pool.map_async(f, (11,)) #Start job 1 
    result1 = pool.map_async(f, (10,)) #Start job 2 
    print "result = ", result.get(timeout=3) 
    print "result1 = ", result1.get(timeout=3) 

예 :

$ python main.py 
slowstart: process id = 97687 (sleep(2)) 
slowstart: process id = 97688 (sleep(3)) 
slowstart: process id = 97689 (sleep(0)) 
slowstart: process id = 97690 (sleep(2)) 
process id = 97689 
process id = 97689 
result = [121] 
result1 = [100] 
+0

요점 https://gist.github.com/dnozay/b2462798ca89fbbf0bf4 – dnozay

관련 문제