Python 使用Popen内部线程的奇怪行为

Python 使用Popen内部线程的奇怪行为,python,subprocess,python-multithreading,Python,Subprocess,Python Multithreading,这里有一个陷阱,我正在运行一个python3脚本,它启动4个线程。每个线程启动另一个脚本(python2)8次 我希望这些调用在调用脚本之前等待结束,这就是我使用p.communicate()和p.wait()的原因 然而,我注意到线程只是忽略了p.communicate()和p.wait(),并在不等待的情况下继续调用popen 下面是我的脚本的简化版本,它们重现了这种行为 Python3脚本 import threading import threading def run_thread(n

这里有一个陷阱,我正在运行一个python3脚本,它启动4个线程。每个线程启动另一个脚本(python2)8次

我希望这些调用在调用脚本之前等待结束,这就是我使用p.communicate()和p.wait()的原因

然而,我注意到线程只是忽略了p.communicate()和p.wait(),并在不等待的情况下继续调用popen

下面是我的脚本的简化版本,它们重现了这种行为

Python3脚本

import threading
import threading
def run_thread(nb_processes):
    for index in range(nb_processes):
      print("Starting {}".format(index))
      call = 'python2 testwait.py'
      p = subprocess.Popen(call.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      p.communicate()
      p.wait()


def main():
    nb_concurrent_threads = 4
    nb_process_to_call_by_thread = 8
    threads = []
    for thread in range(nb_concurrent_threads):
        print("Thread : {}".format(thread))
        t = threading.Thread(target=run_thread, args=[nb_process_to_call_by_thread])
        threads.append(t)
        t.start()
    for thread in threads:
        thread.join()
        print(thread.stdout)
    return

if __name__ == '__main__':
    main()
import time
for i in range(0,100):
  print(i)
  time.sleep(1)
Python2脚本

import threading
import threading
def run_thread(nb_processes):
    for index in range(nb_processes):
      print("Starting {}".format(index))
      call = 'python2 testwait.py'
      p = subprocess.Popen(call.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      p.communicate()
      p.wait()


def main():
    nb_concurrent_threads = 4
    nb_process_to_call_by_thread = 8
    threads = []
    for thread in range(nb_concurrent_threads):
        print("Thread : {}".format(thread))
        t = threading.Thread(target=run_thread, args=[nb_process_to_call_by_thread])
        threads.append(t)
        t.start()
    for thread in threads:
        thread.join()
        print(thread.stdout)
    return

if __name__ == '__main__':
    main()
import time
for i in range(0,100):
  print(i)
  time.sleep(1)
你知道为什么会这样吗?我已经尝试过用call或check_call替换popen,但没有成功

编辑:启动脚本后立即打印“启动2,3,…”,但是由于python2脚本需要一段时间才能运行,因此应该有更多的时间

Thread : 0                                                                                                                                                                                                         
Starting 0                                                                                                                                                                                                         
Thread : 1                                                                                                                                                                                                         
Starting 0                                                                                                                                                                                                         
Thread : 2                                                                                                                                                                                                         
Starting 0                                                                                                                                                                                                         
Thread : 3                                                                                                                                                                                                         
Starting 0                                                                                                                                                                                                         
Starting 1                                                                                                                                                                                                         
Starting 1                                                                                                                                                                                                         
Starting 1                                                                                                                                                                                                         
Starting 2                                                                                                                                                                                                         
Starting 2                                                                                                                                                                                                         
Starting 2                                                                                                                                                                                                         
Starting 3                                                                                                                                                                                                         
Starting 3                                                                                                                                                                                                         
Starting 3                                                                                                                                                                                                         
Starting 4                                                                                                                                                                                                         
Starting 4                                                                                                                                                                                                         
Starting 4                                                                                                                                                                                                         
Starting 5                                                                                                                                                                                                         
Starting 5                                                                                                                                                                                                         
Starting 5                                                                                                                                                                                                         
[.....]
正如jordanm所说,“我的钱在testwait.py上”我们会把你的btc地址寄给我,你是对的。我的日志文件没有捕获stderr。。。我用p.poll()检查了脚本的返回代码,结果确实是1


谢谢

每个线程启动另一个脚本(python2)8次。我很好奇,有没有更好的方法可以做到这一点?我将我的your代码复制到本地机器上,但无法重现您描述的行为。你如何确定它没有等待?你试过打印stdout和stderr吗?
testwait.py
在您当前的工作目录中吗?我的示例是一个简化。每次我都必须用不同的参数运行相同的脚本(python2中的脚本需要一段时间才能运行,这就是为什么我想要多线程)。python3中的脚本负责选择参数。我没有找到更好的方法,但我愿意接受任何想法。@jordanm只是因为“开始1”和“开始2”之间应该有更多的时间,因为python2脚本应该需要一段时间。@MerkleDaamgard这并不意味着
communicate()
工作不正常。很可能您的命令出错并立即退出。我把钱放在“testwait.py”上,它不在您当前的工作目录中。