【问题标题】:Strange behaviour using Popen inside threads在线程内使用 Popen 的奇怪行为
【发布时间】:2020-04-22 17:41:52
【问题描述】:

这就是问题所在,我正在运行一个启动 4 个线程的 python3 脚本。每个线程启动另一个脚本(在 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()

Python2 脚本

import time
for i in range(0,100):
  print(i)
  time.sleep(1)

关于为什么会发生这种情况的任何想法?我已经尝试用 call 或 check_call 替换 popen 没有任何成功。

编辑:“Starting 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                                                                                                                                                                                                         
[.....]

【问题讨论】:

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

标签: python subprocess python-multithreading


【解决方案1】:

正如 jordanm 所说,“我的钱在 testwait.py 上”,请把你的 btc 地址发给我,你是对的。我的日志文件没有捕获到 stderr...我用 p.poll() 检查了脚本的返回码,它确实是 1。

谢谢!

【讨论】:

    猜你喜欢
    • 2018-03-06
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2018-09-30
    相关资源
    最近更新 更多