Python 中的阻塞线程

Blocking threads in Python

我正在调试一些有阻塞问题的 Python 代码。我对那里发生的事情有一些假设,但我不知道 Python 线程机制足以验证它。

代码如下:

class Executor:

    def execute_many(commands):

        with_processes = zip(commands, seld.process_cycle)

        def write():
            for command, process in with_processes:
                send_command_to_process(process, command)

        writing_thread = threading.Thread(target=write)
        writing_thread.start()

        for _, process in with_processes:
            yield receive_result_from_process(process)

        thread.join()

和其他地方:

foos = [make_foo(result) for result in executor.execute_many(commands)]

Executorprocess_cycle 产生 subprocess.Popen 个对象。 send_command_to_processreceive_result_from_process 通过管道与这些进程通信。

我正在调试的问题是此代码有时会冻结:所有 Popen 进程和 writing_thread 在写入管道后在刷新时被阻止。

我没想到它会发生,因为(即使缓冲区已满)execute_many 生成器将 yield receive_result_from_process(process) 并取消阻止其中一个进程(这不会发生 - execute_many 在循环内冻结)。

所以我想出了一个假设,如果writing_thread被一个完整的管道缓冲区阻塞,那么主线程也会被阻塞(它们在同一个进程中)。

这可能吗?如果是,它是 Python 功能,还是 Linux 功能?

TL;DR

如果一个 Python 进程有两个线程,其中一个在写入已满的管道缓冲区后在刷新时被阻塞,是否会阻塞另一个线程?

如果是,它是 Python 功能,还是 Linux 功能?

CPython 中有一个叫做 Global Interpreter Lock 的东西可以防止 python 字节码在不同的线程中被解释。

每个线程都需要主动释放线程,让另一个线程执行。

如果一个线程被阻塞,其他线程肯定可以继续执行。