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

Python 3.x 在等待子进程Popen时,我可以在另一个线程中工作吗,python-3.x,multithreading,subprocess,gil,Python 3.x,Multithreading,Subprocess,Gil,我有一个Python 3.7项目 它使用一个库,该库使用subprocessPopen调用shell脚本 我想知道:如果我们将库调用放在一个单独的线程中,我是否能够在主线程中执行工作,同时在另一个线程中等待来自Popen的结果 这里有一个答案是: Python线程使用GIL的方式是使用一个简单的计数器。 每执行100字节代码,GIL就应该被释放 由当前执行的线程执行,以便为其他线程提供 执行代码的机会。这种行为在Python中基本上被破坏了 2.7因为线程释放/获取机制。它已在Python3中修

我有一个Python 3.7项目

它使用一个库,该库使用subprocess
Popen
调用shell脚本

我想知道:如果我们将库调用放在一个单独的线程中,我是否能够在主线程中执行工作,同时在另一个线程中等待来自
Popen
的结果

这里有一个答案是:

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

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

也许这个信息是错误的

下面是另一个答案,它说:

…口译员始终可以释放GIL;它会给一些人 解释了足够多指令后的其他线程,或 如果它执行了一些I/O,则会自动执行。请注意,自从最近的Python 3.x以来, 标准不再基于执行的数量 指示,但取决于是否经过了足够的时间

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

我知道是哪一个显式地解决了这个问题,但我正在调用一个第三方库,它只使用plain
subprocess.Popen


有人能确认“在单独的线程中调用子流程”的想法是否对我有用,特别是在Python 3.7中吗?

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

我设置了两个文件:

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线程工作:)