2017-03-23 9 views
1

명령 줄 인수를 허용하는 Python 스크립트 job.py이 있습니다. 이 스크립트는 Python 패키지 subprocess을 사용하여 일부 외부 프로그램을 실행합니다. 스크립트와 외부 프로그램 모두 순차적입니다 (예 : MPI, openMP 등). 이 스크립트는 매번 다른 명령 줄 인수로 4 번 실행하고 싶습니다. 내 프로세서에는 4 개의 코어가 있으므로 모든 4 개의 인스턴스를 동시에 실행하고 싶습니다. 4 개의 터미널을 열고 스크립트의 각 인스턴스를 별도의 터미널에서 실행하면 완벽하게 작동하며 원하는대로 정확하게 얻을 수 있습니다.subprocess.call을 사용하는 동일한 Python 스크립트의 여러 인스턴스를 실행하는 방법

이제는 단일 터미널에서 단일 명령으로이 모든 작업을 수행 할 수 있도록 4 인스턴스를 쉽게 시작하고 싶습니다. 이를 위해 bash 스크립트를 사용합니다. batch.sh :

이것은 작동하지 않습니다. subprocess이 여기에있는 것으로 밝혀졌습니다.

[1]+ Stopped     python job.py 4 0 

를 그래서 나는 그것을보고 어떻게 내가 그 자체가 백그라운드에서 다른 뭔가를 실행하려고 백그라운드에서 job.pyjob.py를 실행하려고하고 있다는 점이다 : 그것은 subprocess.call를 돌 때까지 모든 파이썬 코드는 내가 얻을 후 완벽하게 실행 subprocess을 통해 이것은 분명히 이해가 안되는 이유로 작동하지 않습니다.

다중 터미널을 필요로하지 않고 job.py을 여러 번 실행할 수 있습니까?

편집 # 1

는 추천에 나는 multiprocessing, threadthreading 패키지를 시도했다. 가장 좋은 경우에는 하나의 인스턴스 만 제대로 실행되었습니다. 나는 일하는 추악한 해결 방법을 시도했다.

konsole -e python job.py 4 0 
konsole -e python job.py 4 1 
konsole -e python job.py 4 2 
konsole -e python job.py 4 3 

편집 # 다음은 2

subprocess.call 사용하는 실제 기능입니다 (참고 : subprocesssp로 가져가) 나는 새로운 터미널에서 각 인스턴스를 시작 떠들썩한 파티 스크립트를했다.

def run_case(path): 
    case = path['case'] 
    os.chdir(case) 
    cmd = '{foam}; {solver} >log.{solver} 2>&1'.format(foam=CONFIG['FOAM'], 
                 solver=CONFIG['SOLVER']) 
    sp.call(['/bin/bash', '-i', '-c', cmd]) 

은 나를 빈 공간에 채워 보자

  • CONFIG는 전 세계적으로 정의 사전입니다.
  • CONFIG['FOAM'] = 'of40' 이것은 내 바이너리에 속한 파일의 소스로 사용되는 .bashrc의 별칭입니다.
  • CONFIG['SOLVER'] = 'simpleFoam' 이것은 실행중인 이진 파일입니다.

편집 # 3

드디어이

def run_case(): 
    case = CONFIG['PATH']['case'] 
    os.chdir(case) 
    cmd = 'source {foam}; {solver} >log.simpleFoam 2>&1'.format(foam=CONFIG['FOAM'], 
                   solver=CONFIG['SOLVER']) 
    sp.call([cmd], shell=True, executable='/bin/bash') 

솔루션과 함께 작동하도록있어 대신에 실제 명령 줄에서 /bin/bash 등의 모두 shell=Trueexecutable='/bin/bash' 설정했다 껍질에 전달하십시오. 참고 : foam 이제 별칭 대신 파일 경로입니다. 당신은 파이썬 내에서 병렬화 할 수

+0

'중지됨'은 단지'job.py'의 인스턴스가 완료되었다는 것을 의미 할 수 있습니다. – Apalala

+3

이것이'subprocess' 모듈과 관련이 없다고 생각합니다. 실행중인 프로그램이'stdout'에 쓰기를 원한다고 생각하고'SIGTTOU'를 백그라운드에 놓았 기 때문에'SIGTTOU'를 받는다. 그래서 당신의 제어 터미널에 접근 할 수 없다. 이는 표준적인 동작입니다. 프로그램의 결과물을 캡쳐 ('stdout = subprocess.PIPE'와'stderr = subprocess.PIPE') 할 수는 있지만 프로그램 출력을 올바르게 처리해야합니다 ('subprocess.Popen'과'communicate' 메쏘드 참고).). – larsks

+0

다른 코어에 액세스하려면 스레딩을 사용해야합니다. https://www.tutorialspoint.com/python/python_multithreading.htm – Tobey

답변

2

:

그것은 당신이 모니터시키는 장점이있다
import multiprocessing 
import subprocess 

def run_job(spec): 
    ... 
    if spec ...: 
     subprocess.call(...) 

def run_all_jobs(specs): 
    pool = multiprocessing.Pool() 
    pool.map(run_job, specs) 

가// 디버그 병렬화 로그인합니다.

+0

이 작업을 시도했지만 작업 중 하나만 실행합니다. 풀에서 다른 것을 실행하려면 터미널에'fg'를 입력해야합니다. 'subprocess.call' 이전의 모든 것이 예상대로 실행되기 때문에 어떻게 든'subprocess.call'는 잠금 동작을합니다. 모든'subprocess.call'을 주석 처리하면 완료 될 때까지 모든 작업이 실행됩니다 (자연스럽게 아무 것도하지 않고). – mtgoncalves

+0

'subprocess.call()'으로 무엇을 부르시겠습니까? 'shell = True'를 사용하고 있습니까? – Apalala

+0

나는'shell'을'True'와'False'로 설정하여 시험해 보았습니다. 'subprocess.call'을 사용하는 함수를 보려면 OP의 ** EDIT # 2 **를 참조하십시오. – mtgoncalves