我正在调试一些有阻塞问题的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)]
process_cycle
的{{1}}会产生Executor
个对象。 subprocess.Popen
和send_command_to_process
通过管道与这些流程进行通信。
我调试的问题是这段代码不时冻结:写入管道后,所有receive_result_from_process
进程和Popen
在刷新时被阻止。
我没想到会发生这种情况,因为(即使缓冲区已满)writing_thread
生成器将execute_many
并取消阻止其中一个进程(不会发生 - yield receive_result_from_process(process)
冻结在循环内部。)
所以我提出了一个假设,即如果execute_many
被一个完整的管道缓冲区阻塞,那么主线程也会被阻塞(它们处于同一个进程中)。
这可能吗?如果是这样的话,那就是Python功能或Linux功能?
TL; DR
如果Python进程有两个线程,其中一个在写入完整管道缓冲区后在刷新时被阻塞,那么是否会阻塞另一个线程?
如果是,那么它是Python功能还是Linux功能?
答案 0 :(得分:2)
CPython中有一个叫Global Interpreter Lock的东西,它可以防止python字节码被解释为不同的线程。
每个线程都需要主动释放线程,以便另一个线程可以执行。
答案 1 :(得分:1)
如果一个线程被阻塞,其他线程可以继续执行。