2016-08-22 635 views
1

我很感谢线程的一些帮助,这是我很新的东西。Python:在一个线程中停止另一个线程从另一个线程结束

示例代码并不完全是我正在做的('记事本'和'calc'只是示例命令),但是显示我的问题的简化版本。

我想运行两个独立的线程,每个线程多次运行不同的命令。我想代码做到这一点:当我关闭的“记事本”实例

  1. 启动“记事本”和“计算”同时 (它确实)
  2. 的第一个实例,打开 '记事本'的下一个实例。
  3. 当我关闭'calc'的实例时,打开 下一个'calc'实例。
  4. 我希望脚本等到两个线程都完成后,因为它需要对这些输出进行一些处理。

然而,当我关闭“记事本”的一个实例,“记事本”的下一个实例不会启动,直到我已经关闭“钙”的当前实例,反之亦然。随着一些排除错误,它看起来像'记事本'封闭实例的过程(来自Popen)直到当前'calc'被关闭才会结束。

在Windows上运行的Python 2.7 7

示例代码:提前

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() 

感谢:-)

尼克

+0

而不是使用'Popen'和'communic'来启动一个cmd,难道你不能启动真正的可执行文件吗?像'subprocess.call(['notepad.exe'])'? (我没有Windows,所以你必须找到你必须使用的确切名称)。 – Bakuriu

+0

@Bakuriu - 感谢您的参与。我考虑使用调用,但我需要stdout和stderr,并且文档中提到“注意:不要对此函数使用stdout = PIPE或stderr = PIPE,因为它可能会根据子进程的输出量死锁。请使用Popen和communicate()方法当你需要管道。“ –

+0

@NickFromage如果你需要标准输出你可能想使用['check_output'](https://docs.python.org/3/library/subprocess.html#subprocess.check_output)。基本上是'call' +'stdout = PIPE',它使用'communic'来获得输出。 – Bakuriu

回答

0

所以communicate()方法显然是等待创建的进程通过Popen并执行cmd.exe并启动了一个几乎在同一时间终止。因为,在几乎相同的时间运行Notepadcmd.exe,运行calculator开始的cmd.execommunicate()电话(一个在A_thread,一个在B_thread)等待两个处理期限。因此for循环都不会进行,直到两个过程成熟为止。

在启动两个线程之间添加延迟可以解决问题。

所以,让你的原始代码不变,并添加

sleep(1) 

两个Threadstarts之间产生所需的行为。

在我的系统上,增加延迟0.0001秒可以可靠地解决问题,而延迟0.00001则不能。

+0

“睡(1)”似乎工作。非常感谢您的帮助:-) –