2016-08-22 6 views
1

스레딩에 대한 도움을 주시면 감사하겠습니다.파이썬 : 다른 스레드의 프로세스를 멈추는 하나의 스레드에서 처리 완료

예제 코드는 정확히 내가하고있는 것 ('notepad'및 'calc'는 예제 명령)이지만 내 문제를 보여주는 단순화 된 버전입니다.

각각 다른 명령을 여러 번 실행하는 두 개의 별도 스레드를 실행하고 싶습니다. 를 열고, 나는 '메모장'의 인스턴스를 닫으면

    는 '메모장'과 (가 않습니다) 동시에 'CALC'
  1. 의 첫 번째 인스턴스를 시작
  2. : 나는이 작업을 수행하는 코드를 싶습니다 '메모장'의 다음 인스턴스입니다.
  3. 'calc'인스턴스를 닫으면 으로 'calc'의 다음 인스턴스를 엽니 다.
  4. [편집] 두 개의 쓰레드가 끝날 때까지 기다려야합니다. 출력을 처리해야하기 때문입니다. 나는 '메모장'의 인스턴스를 닫을 때 나는 반대 'CALC'의 현재 인스턴스를 폐쇄 할 때까지 그러나

, '메모장'의 다음 인스턴스가 시작되지 않습니다. de-bugging을 조금하면 'notepad'의 닫힌 인스턴스에 대한 Popen의 프로세스가 현재 'calc'가 닫힐 때까지 완료되지 않은 것처럼 보입니다.

+0

대신 'Popen'을 사용하고 cmd를 실행하기 위해'communicate'를 사용하면 실제 실행 파일을 시작할 수 없습니까? 'subprocess.call ([ 'notepad.exe'])'와 비슷합니까? (저는 Windows가 없으므로 사용하는 정확한 이름을 찾아야합니다.) – Bakuriu

+0

@Bakuriu - 의견을 보내 주셔서 감사합니다.나는 전화를 사용하는 것을 고려했다. 그러나 stdout과 stderr가 필요하고 문서에는 "Note stdout = PIPE 나 stderr = PIPE는 자식 프로세스 출력 볼륨을 기반으로 교착 상태가 될 수 있으므로이 함수를 사용하지 마십시오. 파이프가 필요할 때 사용할 수 있습니다. " –

+0

@NickFromage stdout이 필요한 경우 [check_output'] (https://docs.python.org/3/library/subprocess.html#subprocess.check_output)을 사용할 수 있습니다. 기본적으로'call' +'stdout = PIPE'는 출력을 얻기 위해'communicate'를 사용합니다. – Bakuriu

답변

0

는 그래서 communicate() 방법은 분명히 생성 된 모든 프로세스를 기다리는 :-) 사전에

from subprocess import Popen, PIPE, STDOUT 
from threading import Thread 

def do_commands(command_list): 

    for command in command_list: 
     proc = Popen("cmd.exe", stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
     stdout_value, stderr_value = proc.communicate(input=command) 

# MAIN CODE 
A_command_list = ["notepad\n", "notepad\n", "notepad\n" ] 
B_command_list = ["calc\n", "calc\n", "calc\n" ] 

A_args = [A_command_list] 
B_args = [B_command_list] 

A_thread = Thread(target=do_commands, args=(A_args)) 
B_thread = Thread(target=do_commands, args=(B_args)) 

A_thread.start() 
B_thread.start() 

A_thread.join() 
B_thread.join() 

감사 : 7

예제 코드를 윈도우에서 파이썬 2.7을 실행

Popen으로 실행하고 cmd.exe을 실행하고 거의 같은 시간에을 종료하십시오. 두 용어를 처리 할 때까지 Notepad를 실행하는 cmd.exe, 거의 동시에 calculator 시작을 실행하는 cmd.exe 때문에 모두 communicate() 호출 (A_thread에서 하나 B_thread 하나) 기다립니다. 따라서 for 두 프로세스 기간까지 루프가 진행되지 않습니다.

두 스레드 시작 사이에 지연을 추가하면 문제가 해결됩니다.

그래서, 변경되지 않은 원래의 코드를 떠나 두 Threadstarts 사이

sleep(1) 

를 추가하면 원하는 동작을 생산하고 있습니다.

내 시스템에서 0.0001 초 지연을 추가하면 문제가 안정적으로 해결되지만 0.00001 지연은 문제를 해결하지 못했습니다.

+0

"sleep (1)"이 작동하는 것 같습니다. 도움을 청합니다 :-) –