2016-08-22 632 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)」似乎工作。非常感謝您的幫助:-) –