별도의 파일 / 스크립트를 쓰거나 쓰지 않고 하위 프로세스에서 함수를 실행할 수 있습니까?


82
import subprocess

def my_function(x):
    return x + 100

output = subprocess.Popen(my_function, 1) #I would like to pass the function object and its arguments
print output 
#desired output: 101

별도의 스크립트를 사용하여 하위 프로세스를 여는 것에 대한 문서 만 찾았습니다. 누구든지 함수 객체를 전달하는 방법 또는 함수 코드를 전달하는 쉬운 방법을 알고 있습니까?


1
나는 당신이 다중 처리 모듈을 찾고 있다고 생각합니다 .
Noctis Skytower

답변:


111

다중 처리 모듈과 같은 것을 찾고 있다고 생각합니다.

http://docs.python.org/library/multiprocessing.html#the-process-class

하위 프로세스 모듈은 프로세스를 생성하고 입력 / 출력으로 작업을 수행하기위한 것이며 함수를 실행하기위한 것이 아닙니다.

다음은 multiprocessing코드 버전입니다.

from multiprocessing import Process, Queue

def my_function(q, x):
    q.put(x + 100)

if __name__ == '__main__':
    queue = Queue()
    p = Process(target=my_function, args=(queue, 1))
    p.start()
    p.join() # this blocks until the process terminates
    result = queue.get()
    print result

20
processify데코레이터를 바로 가기로 사용할 수 있습니다 . gist.github.com/2311116
schlamar

3
이것이 Python 인터프리터와 하위 프로세스의 모든 환경을 복제한다고 가정합니까?
Jens

1
다음은 python 3에서 작동하고 생성기 함수를 지원하는 processify 포크입니다. gist.github.com/stuaxo/889db016e51264581b50
Stuart Axon

4
이 코드는 큐를 통해 아주 큰 데이터를 전달하는 경우 교착 상태를 포함합니다. 프로세스에 참여하기 전에 항상 queue.get ()을 사용합니다.
Petr Baudis 2017 년

@schlamar 백그라운드에서 함수를 실행하고 싶지만 리소스 제한이있어 원하는만큼 함수를 실행할 수 없으며 함수의 추가 실행을 대기열에 추가하고 싶습니다. 어떻게해야하는지 아십니까? 여기에 내 질문이 있습니다 . 제 질문 좀 봐주 시겠어요? 어떤 도움이라도 좋을 것입니다!
Amir

17

표준 Unix fork시스템 호출을 os.fork(). fork()동일한 스크립트가 실행되는 새 프로세스를 만듭니다. 새 프로세스에서는 0을 반환하고 이전 프로세스에서는 새 프로세스의 프로세스 ID를 반환합니다.

child_pid = os.fork()
if child_pid == 0:
  print "New proc"
else:
  print "Old proc"

다중 프로세스 사용을위한 이식 가능한 추상화를 제공하는 다중 처리 지원을 제공하는 상위 수준 라이브러리의 경우 다중 처리 모듈이 있습니다. 두 기술에 대한 간략한 소개와 함께 IBM DeveloperWorks, Multiprocessing with Python 에 대한 기사가 있습니다 .


궁금해; 왜 반대표? 내 대답에 잘못된 것이 있습니까?
Brian Campbell

멀티 프로세싱은 fork ()에 대한 상위 레벨 래퍼가 아니라 멀티 플랫폼 멀티 프로세싱 툴킷 (유닉스에서 fork를 사용)입니다. 이것은 Windows에서 실행되는 반면 fork ()는 실행되지 않기 때문에 중요합니다. 편집 : 그리고 이것은 나중에 그것이 아마도 가치가 없다고 결정했지만, 이것이 반대표의 이유였습니다. 그래도 되찾기에는 너무 늦었습니다. Edit2 : 또는 오히려 교차 플랫폼이 아닌 경우 fork () 제안이 이유였습니다.
Devin Jeanpierre 2010 년

3
@Devin, 원하는 경우 언제든지 다운 투표를 취소 할 수 있습니다.
Alex Martelli

이를 명확히하기 위해 편집했습니다. 나는 fork그것이 이식성이 없다고 명시 적으로 언급했다 . 나는 일반적으로 휴대 할 수 없다는 정보와 함께 휴대 할 수없는 답변을 제공하고 질문자가 그들에게 충분한 지 결정하도록 할 것입니다. 내 답변을 편집 했으므로 내가 충분히 개선했다고 생각되면 반대표를 제거 할 수 있습니다. 당신이 그렇지 않으면 어려운 감정은 없지만 나는 단지 내가 뭘 잘못했는지 확인하고 싶었습니다.
Brian Campbell

@Alex, 아니, 당신은 할 수 없습니다. 일정 시간이 지나면 편집이 이루어질 때까지 되돌릴 수 없습니다. 내가 다시 생각하기까지 그토록 많은 시간이 지났기 때문에 "너무 늦었다"는 의견이 나왔다. 어쨌든, 내가 말했듯이, 나는 그만한 가치가 없다고 결정했기 때문에 사라졌습니다. 나는 또한 당신의 이유를 감사하고 이해하며, 어느 쪽이든 어려운 감정이 없다는 것을 기쁘게 생각합니다. : p
Devin Jeanpierre 2010 년

5

다중 처리에 대한 Brian McKenna의 위 게시물은 정말 도움이되지만 스레드 경로 (프로세스 기반과 반대)로 이동하려는 경우이 예제를 통해 시작할 수 있습니다.

import threading
import time

def blocker():
    while True:
        print "Oh, sorry, am I in the way?"
        time.sleep(1)

t = threading.Thread(name='child procs', target=blocker)
t.start()

# Prove that we passed through the blocking call
print "No, that's okay" 

setDaemon(True)기능을 사용 하여 스레드를 즉시 백그라운드로 만들 수도 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.