아래 예제 코드에서 함수의 반환 값을 복구하고 싶습니다 worker
. 이 작업을 어떻게 수행 할 수 있습니까? 이 값은 어디에 저장됩니까?
예제 코드 :
import multiprocessing
def worker(procnum):
'''worker function'''
print str(procnum) + ' represent!'
return procnum
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
print jobs
산출:
0 represent!
1 represent!
2 represent!
3 represent!
4 represent!
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, stopped)>, <Process(Process-5, stopped)>]
에 저장된 객체에서 관련 속성을 찾을 수 없습니다 jobs
.
답변
공유 변수 를 사용 하여 통신하십시오. 예를 들면 다음과 같습니다.
import multiprocessing
def worker(procnum, return_dict):
'''worker function'''
print str(procnum) + ' represent!'
return_dict[procnum] = procnum
if __name__ == '__main__':
manager = multiprocessing.Manager()
return_dict = manager.dict()
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,return_dict))
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
print return_dict.values()
답변
@sega_sai가 제안한 접근법이 더 낫다고 생각합니다. 그러나 실제로 코드 예제가 필요하므로 다음과 같이하십시오.
import multiprocessing
from os import getpid
def worker(procnum):
print('I am number %d in process %d' % (procnum, getpid()))
return getpid()
if __name__ == '__main__':
pool = multiprocessing.Pool(processes = 3)
print(pool.map(worker, range(5)))
반환 값을 인쇄합니다 :
I am number 0 in process 19139
I am number 1 in process 19138
I am number 2 in process 19140
I am number 3 in process 19139
I am number 4 in process 19140
[19139, 19138, 19140, 19139, 19140]
map
(Python 2 내장)에 익숙하다면 너무 도전해서는 안됩니다. 그렇지 않으면 sega_Sai의 링크를 살펴보십시오 .
코드가 거의 필요하지 않습니다. 또한 프로세스를 재사용하는 방법에 유의하십시오.
답변
이 예제는 multiprocessing.Pipe 인스턴스 목록을 사용 하여 임의의 수의 프로세스에서 문자열을 반환 하는 방법을 보여줍니다 .
import multiprocessing
def worker(procnum, send_end):
'''worker function'''
result = str(procnum) + ' represent!'
print result
send_end.send(result)
def main():
jobs = []
pipe_list = []
for i in range(5):
recv_end, send_end = multiprocessing.Pipe(False)
p = multiprocessing.Process(target=worker, args=(i, send_end))
jobs.append(p)
pipe_list.append(recv_end)
p.start()
for proc in jobs:
proc.join()
result_list = [x.recv() for x in pipe_list]
print result_list
if __name__ == '__main__':
main()
산출:
0 represent!
1 represent!
2 represent!
3 represent!
4 represent!
['0 represent!', '1 represent!', '2 represent!', '3 represent!', '4 represent!']
이 솔루션은 멀티 프로세싱 보다 적은 리소스 를 사용합니다.
- 파이프
- 적어도 하나의 자물쇠
- 버퍼
- 실
또는 멀티 프로세싱 을 사용 하는 SimpleQueue
- 파이프
- 적어도 하나의 자물쇠
이러한 각 유형의 소스를 보는 것이 매우 유익합니다.
답변
어떤 이유로 든 어디서나이 작업을 수행하는 방법에 대한 일반적인 예를 찾을 수 없었습니다 Queue
(파이썬의 doc 예제는 여러 프로세스를 생성하지 않습니다). 그래서 10 번 시도한 후에 작업 한 내용은 다음과 같습니다.
def add_helper(queue, arg1, arg2): # the func called in child processes
ret = arg1 + arg2
queue.put(ret)
def multi_add(): # spawns child processes
q = Queue()
processes = []
rets = []
for _ in range(0, 100):
p = Process(target=add_helper, args=(q, 1, 2))
processes.append(p)
p.start()
for p in processes:
ret = q.get() # will block
rets.append(ret)
for p in processes:
p.join()
return rets
Queue
하위 프로세스의 리턴 값을 저장하는 데 사용할 수있는 차단 스레드 안전 큐입니다. 따라서 각 프로세스에 큐를 전달해야합니다. 여기에 덜 분명 뭔가는해야한다는 것입니다 get()
전에 대기열에서 ES 또는 다른 큐가 가득하고 차단 다.join
Process
객체 지향적 인 사람들을 위해 업데이트하십시오 (Python 3.4에서 테스트 됨).
from multiprocessing import Process, Queue
class Multiprocessor():
def __init__(self):
self.processes = []
self.queue = Queue()
@staticmethod
def _wrapper(func, queue, args, kwargs):
ret = func(*args, **kwargs)
queue.put(ret)
def run(self, func, *args, **kwargs):
args2 = [func, self.queue, args, kwargs]
p = Process(target=self._wrapper, args=args2)
self.processes.append(p)
p.start()
def wait(self):
rets = []
for p in self.processes:
ret = self.queue.get()
rets.append(ret)
for p in self.processes:
p.join()
return rets
# tester
if __name__ == "__main__":
mp = Multiprocessor()
num_proc = 64
for _ in range(num_proc): # queue up multiple tasks running `sum`
mp.run(sum, [1, 2, 3, 4, 5])
ret = mp.wait() # get all results
print(ret)
assert len(ret) == num_proc and all(r == 15 for r in ret)
답변
Process
using 에서 가치를 얻는 방법을 찾고있는 다른 사람들을 위해 Queue
:
import multiprocessing
ret = {'foo': False}
def worker(queue):
ret = queue.get()
ret['foo'] = True
queue.put(ret)
if __name__ == '__main__':
queue = multiprocessing.Queue()
queue.put(ret)
p = multiprocessing.Process(target=worker, args=(queue,))
p.start()
print queue.get() # Prints {"foo": True}
p.join()
답변
당신이 사용해야하는 것 같습니다 multiprocessing.Pool의 ) (지도 대신 클래스 등) (.apply .apply_async을 () 메서드를 사용
http://docs.python.org/library/multiprocessing.html?highlight=pool#multiprocessing.pool.AsyncResult
답변
exit
내장을 사용하여 프로세스의 종료 코드를 설정할 수 있습니다 . exitcode
프로세스 의 속성 에서 얻을 수 있습니다 .
import multiprocessing
def worker(procnum):
print str(procnum) + ' represent!'
exit(procnum)
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
jobs.append(p)
p.start()
result = []
for proc in jobs:
proc.join()
result.append(proc.exitcode)
print result
산출:
0 represent!
1 represent!
2 represent!
3 represent!
4 represent!
[0, 1, 2, 3, 4]