【问题标题】:Blocking threads in PythonPython中的阻塞线程
【发布时间】:2015-03-16 22:53:10
【问题描述】:

我正在调试一些存在阻塞问题的 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 功能?

【问题讨论】:

  • 您能否提供完整的程序以及如何启动它的错误和说明?
  • 对不起,但不是真的。这些锁只是偶尔发生,并且只有在命令花费大量时间并刷新大量数据(它们实际上发出请求)时才会发生。代码的最小相关子集不会阻塞,我无法发布完整代码,因为它是我的雇主财产。
  • 也许你可以创建一些模型,玩具示例?

标签: python linux multithreading pipe


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回答。我知道吉尔。问题是:如果一个Python线程被一个完整的管道阻塞,它会释放锁吗?
【解决方案2】:

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

【讨论】:

  • 谢谢你,它帮助我发现了实际的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多