在等待子进程Popen时,我可以在另一个线程中工作吗?

问题描述 投票:0回答:1

我有一个Python 3.7项目

它使用的库使用子进程Popen来调用shell脚本。

我想知道:如果要将库调用放在一个单独的线程中,我是否能够在主线程中等待来自另一个线程中的Popen的结果?

这里有一个答案https://stackoverflow.com/a/33352871/202168说:

Python线程与GIL一起使用的方式是使用简单的计数器。执行每100个字节代码时,GIL应该由当前正在执行的线程释放,以便为其他线程提供执行代码的机会。由于线程释放/获取机制,在Python 2.7中基本上破坏了这种行为。它已在Python 3中修复。

无论哪种方式对我想做的事情都没有特别的希望。听起来,如果“库调用”线程在调用Popen.wait时没有达到100字节码触发点那么可能它不会切换到我的其他线程,整个应用程序将等待子进程?

也许这个信息是错误的。

这是另一个答案https://stackoverflow.com/a/16262657/202168说:

......口译员总能释放GIL;它会在解释了足够的指令后将其提供给其他一些线程,或者在它执行某些I / O时自动将其提供给其他线程。请注意,自最近的Python 3.x起,标准不再基于已执行指令的数量,而是基于是否已经过了足够的时间。

这听起来更有希望,因为可能与子进程通信将涉及I / O,因此可能允许我的主线程的上下文切换能够在此期间继续进行。 (或者只是等待wait的时间会导致上下文切换)

我知道https://docs.python.org/3/library/asyncio-subprocess.html明确解决了这个问题,但我称之为第三方库,只使用普通的subprocess.Popen

任何人都可以确认“单独线程中的子进程调用”是否可能对我有用,特别是在Python 3.7中?

python-3.x multithreading subprocess gil
1个回答
0
投票

我有时间做一个实验,所以我会回答我自己的问题......

我设置了两个文件:

mainthread.py

#!/usr/bin/env python
import subprocess
import threading
import time


def run_busyproc():
    print(f'{time.time()} Starting busyprocess...')
    subprocess.run(["python", "busyprocess.py"])
    print(f'{time.time()} busyprocess done.')


if __name__ == "__main__":
    thread = threading.Thread(target=run_busyproc)
    print("Starting thread...")
    thread.start()
    while thread.is_alive():
        print(f"{time.time()} Main thread doing its thing...")
        time.sleep(0.5)
    print("Thread is done (?)")
    print("Exit main.")

busyprocess.py

#!/usr/bin/env python
from time import sleep


if __name__ == "__main__":
    for _ in range(100):
        print("Busy...")
        sleep(0.5)
    print("Done")

从命令行运行mainthread.py我可以看到有一个你希望看到的上下文切换 - 主线程能够在等待子进程的结果时工作:

Starting thread...
1555970578.20475 Main thread doing its thing...
1555970578.204679 Starting busyprocess...

Busy...
1555970578.710308 Main thread doing its thing...
Busy...
1555970579.2153869 Main thread doing its thing...
Busy...
1555970579.718168 Main thread doing its thing...
Busy...
1555970580.2231748 Main thread doing its thing...
Busy...
1555970580.726122 Main thread doing its thing...
Busy...
1555970628.009814 Main thread doing its thing...

Done
1555970628.512945 Main thread doing its thing...

1555970628.518155 busyprocess done.
Thread is done (?)
Exit main.

各位好消息,python线程工作:)

© www.soinside.com 2019 - 2024. All rights reserved.