Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:一个线程中的进程阻止另一个线程中的进程完成_Python_Multithreading_Subprocess_Popen_Terminate - Fatal编程技术网

Python:一个线程中的进程阻止另一个线程中的进程完成

Python:一个线程中的进程阻止另一个线程中的进程完成,python,multithreading,subprocess,popen,terminate,Python,Multithreading,Subprocess,Popen,Terminate,如果你能帮我穿线,我会很感激的,这对我来说是个新手 示例代码并不完全是我正在做的(“notepad”和“calc”只是示例命令),而是一个显示我的问题的简化版本 我想运行两个独立的线程,每个线程多次运行不同的命令。我希望代码能够做到这一点: 同时启动“记事本”和“计算”的第一个实例 (确实如此) 当我关闭“记事本”实例时,打开 “记事本”的下一个实例 当我关闭“calc”的实例时 打开“calc”的下一个实例 [编辑]我希望脚本等待两个线程完成,因为它需要对这些线程的输出进行一些处理 但是,当我

如果你能帮我穿线,我会很感激的,这对我来说是个新手

示例代码并不完全是我正在做的(“notepad”和“calc”只是示例命令),而是一个显示我的问题的简化版本

我想运行两个独立的线程,每个线程多次运行不同的命令。我希望代码能够做到这一点:

  • 同时启动“记事本”和“计算”的第一个实例 (确实如此)
  • 当我关闭“记事本”实例时,打开 “记事本”的下一个实例
  • 当我关闭“calc”的实例时 打开“calc”的下一个实例
  • [编辑]我希望脚本等待两个线程完成,因为它需要对这些线程的输出进行一些处理
  • 但是,当我关闭一个“记事本”实例时,“记事本”的下一个实例在我关闭当前“calc”实例之前不会启动,反之亦然。通过一点除错,看起来关闭的“记事本”实例的过程(从Popen开始)在当前“calc”关闭之前不会结束

    在Windows7上运行Python 2.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()
    
    提前感谢:-)

    Nick

    因此
    communicate()
    方法显然在等待由
    Popen
    创建并执行
    cmd.exe
    的所有进程,这些进程几乎在同一时间启动以终止。由于运行
    calculator
    cmd.exe
    与运行
    Notepad
    cmd.exe
    几乎在同一时间启动,因此这两个
    communicate()
    调用(一个在
    A_线程中,一个在
    B_线程中,一个在
    中)都要等待,直到这两个进程结束。因此,在这两个进程结束之前,
    循环都不会前进

    在启动两个线程之间添加延迟可以修复该问题

    因此,保持原始代码不变并添加

    sleep(1)
    
    在两个
    线程之间
    启动
    产生所需的行为


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

    睡眠(1)”似乎有效。非常感谢您的帮助:-)您不能使用
    Popen
    communicate
    来启动cmd,而只是启动实际的可执行文件吗?像
    子进程调用(['notepad.exe'])
    ?(我没有Windows,所以你必须找到你必须使用的确切名称)。@Bakuriu-谢谢你的输入。我考虑过使用call,但我需要stdout和stderr,文档中说“注意,不要将stdout=PIPE或stderr=PIPE与此函数一起使用,因为这可能会基于子进程输出卷发生死锁。当需要管道时,请将Popen与communicate()方法一起使用。”@NickFromage如果需要stdout,您可能需要使用。基本上是
    call
    +
    stdout=PIPE
    ,它使用
    communicate
    获得输出。@Bakuriu-谢谢。我试过用check_输出代替Popen/communicate。它运行相同,但也有相同的问题(需要“sleep”命令停止它,等待两个进程结束)。check_输出看起来确实有点整洁,所以我以后会尝试使用它。:-)我真的不明白为什么需要
    sleep
    hack。如果我有时间,我会试着考虑一下。在任何情况下,我相信
    sleep
    所做的只是触发调度程序。