Skip to main content
 首页 » 编程设计

python之我会遇到 python 的全局解释器锁的问题吗

2024年10月24日32jillzhang

我知道这个问题相当高级,可能含糊不清。请询问您是否需要更多详细信息,我会尝试进行编辑。

我正在使用 QuickFix 和 Python 绑定(bind)来同时使用来自大约 30 个市场的高吞吐量市场数据。大多数计算工作是通过 multiprocessing 模块在单独的 CPU 中完成的。这些并行进程由主进程在启动时产生。如果我希望通过 QuickFix 以任何方式与市场交互,我必须在主进程中执行此操作,因此来自子进程的任何命令(例如输入订单)必须是在执行之前通过管道(通过 mp.Queue 对象,我们将调用 Q)到主进程。

这就产生了监控Q的问题,它必须在主进程中完成。我不能使用 Q.get(),因为这个方法会阻塞并且我的整个主进程将挂起,直到某些东西出现在 Q 中。为了减少延迟,我必须经常检查 Q,大约每秒 50 次。我一直在使用 apscheduler这样做,但我不断收到警告错误,指出缺少运行时。这些错误是一个严重的问题,因为它们使我无法轻松查看重要信息。

因此,我重构了我的应用程序,以使用 MestreLion 发布的代码作为对 this question 的回答。 .这对我有用,因为它从主进程启动一个新线程,并且不打印错误消息。但是,我担心这会在未来引起严重的问题。

我知道 python 中的全局解释器锁(这就是我开始使用 multiprocessing 模块的原因),但我并不真正理解它。由于我的应用程序的高频特性,我不知道 Q 监控线程和消耗大量传入消息的主进程是否会争夺资源并相互拖慢速度。

我的问题:

  1. 在这种情况下我会遇到麻烦吗?

  2. 如果不行,我可以使用目前的方法添加更多监控线程并且仍然没问题吗?至少还有两件事我想高频监控。

谢谢。

请您参考如下方法:

@MestreLion's solution在您的情况下,您链接的每秒创建 50 个线程。

您只需要一个线程来使用队列而不阻塞主进程的其余部分:

import threading 
 
def consume(queue, sentinel=None): 
    for item in iter(queue.get, sentinel): 
        pass_to_quickfix(item) 
 
threading.Thread(target=consume, args=[queue], daemon=True).start() 

在这种情况下,GIL 可能对性能有影响,也可能没有影响。测量一下。