첫째, 이유는 작동하지 않습니다
는
os.system
를 호출 할 때마다 그냥 브랜드 -을 생성 플랫폼의 system
(또는 _system
, 일부 Windows 플랫폼) 함수를 호출 매번 새로운 쉘 프로세스. 따라서 os.system
을 사용하여 다른 통화에 영향을 줄 수있는 방법이 없습니다. 당신이 임의의 프로세스에^C를 보내려면
, 그 os.kill
로 할 수 있습니다.
def send_ctrl_c(pid):
try:
sig = signal.CTRL_C_EVENT
except AttributeError:
sig = signal.SIGINT
else:
os.signal(pid, sig)
그러나, 당신은 다른 프로세스의 pid는 그렇게 할 필요가 있고, os.system
당신에게 그것을 제공하지 않습니다 : 그것은 휴대용하려면, 당신은 이런 식으로 뭔가를해야한다. 여기에 쉘을 사용하는 좋은 이유가 없기 때문에
proc2 = None
def show2():
global proc2
proc2 = subprocess.Popen('ola_recorder -p MyRecord', shell=True)
proc2.wait()
, 당신은 아마 더 나을 것 Popen
목록을 통과 :
그래서, 옳은 일이 subprocess
모듈을 사용하는 것입니다 문자열 대신 args를 사용하고 shell=True
을 남겨 둡니다. 그리고 물론 글로벌에 proc2
을 붙이지 않는 것이 훨씬 깔끔할 것입니다,하지만이 장난감 예제에서는 무시할 것입니다.
어쨌든, 지금은 PID를 얻을 사용할 수 있습니다 : 당신이 그것을 할 거라면
def stop():
send_ctrl_c(proc2.pid)
그러나, 당신은뿐만 아니라 단지 직접 Popen
객체를 사용할 수 있습니다. 당신이 그것으로 무엇을 할 수 있는지의 자세한 내용에 대한 the docs를 참조하지만, 여기에 빠른 버전입니다 : 그것은^C (POSIX)를받은 것처럼
def stop():
global proc2
try:
sig = signal.CTRL_C_EVENT
except AttributeError:
sig = signal.SIGINT
proc.send_signal(sig)
당신이 stop
전화
는, 프로세스가 정확히 살해됩니다하거나 가능한 한^C (Windows)를받은 것처럼 가깝게,
wait
호출은 (최소한 POSIX에서는 -2로) 리턴 할 것이고 스레드도 끝날 것입니다.
마지막 주 : 직접 thread
모듈을 사용하려면 거의 절대, 당신은 threading.Thread
객체를 다시 사용하고 싶지 않아요.그래서, 대신의 :
b = Button(root, text="Show 1", command=lambda: thread.start_new(show1,()))
... 나이 :
b2 = Button(root, text="Show 2", command=lambda: t.start())
은 ... 이렇게 :
def start2():
global t2
t2 = threading.Thread(name='Show2', target=show2)
t2.start()
은 물론, 비 장난감 프로그램은 글로벌을 사용하지 않아야합니다, 마지막 스레드 대신 모든 기존 스레드를 추적하고자 할 것입니다 (백그라운드 스레드가 이미 실행 중일 때 버튼을 클릭 할 수있는 경우). join
모두 필요합니다. 스레드를 종료합니다.
[Tkinter에서 외부 서브 프로세스를 시작/중지하는 방법에 대한 예제] (https://gist.github.com/zed/4067619). 다음은 [스레드를 사용하여 하위 프로세스의 출력을 읽는 비슷한 예입니다 (https://gist.github.com/zed/42324397516310c86288). – jfs
이 예제를 살펴보면서 스레드 코드를 약간 정리할 수 있었지만 프로세스를 멈출 수는 없습니다. 어떤 아이디어? – user808996
'p = Popen()'을 사용하여 서브 프로세스를 시작하고'p.terminate()'를 사용하여 예제와 같이 중지하십시오. – jfs