使用子进程模块是否释放python GIL?

Sim*_*ker 10 python multithreading subprocess gil python-multithreading

当调用通过Python subprocess模块花费相对较长时间的linux二进制文件时,这会释放GIL吗?

我想并行化一些从命令行调用二进制程序的代码.是否更好地使用线程(通过threading和a multiprocessing.pool.ThreadPool)或multiprocessing?我的假设是,如果subprocess发布GIL,那么选择该threading选项会更好.

pil*_*row 15

当调用通过Python subprocess模块花费相对较长时间的linux二进制文件时,这会释放GIL吗?

是的,它在调用过程中释放全局解释器锁(GIL).

正如你可能知道,在POSIX平台subprocess提供从上面的"原始"组件便捷接口fork,execvewaitpid.

通过对CPython的2.7.9源的检查,fork并且execve不会释放GIL.但是,这些调用不会阻塞,因此我们不希望释放GIL.

waitpid当然阻止,但是我们看到它的实现确实使用ALLOW_THREADS宏放弃了GIL:

static PyObject *
posix_waitpid(PyObject *self, PyObject *args)
{
....
Py_BEGIN_ALLOW_THREADS
pid = waitpid(pid, &status, options);
Py_END_ALLOW_THREADS
....
Run Code Online (Sandbox Code Playgroud)

这也可以通过呼唤像一些长期运行的程序进行测试睡眠从演示多线程python脚本.


jfs*_*jfs 5

GIL 不跨越多个进程。subprocess.Popen开始一个新的进程。如果它启动一个 Python 进程,那么它将拥有自己的 GIL。

multiprocessing如果您只想并行运行一些 linux 二进制文件,则不需要多个线程(或由 创建的进程):

from subprocess import Popen

# start all processes
processes = [Popen(['program', str(i)]) for i in range(10)]
# now all processes run in parallel

# wait for processes to complete
for p in processes:
    p.wait()
Run Code Online (Sandbox Code Playgroud)

您可以使用multiprocessing.ThreadPool来限制并发运行程序的数量