我知道这个问题相当高级,可能含糊不清。请询问您是否需要更多详细信息,我会尝试编辑。
我正在使用QuickFix
Python
绑定来同时消耗大约30个市场的高吞吐量市场数据。大多数计算工作都是通过multiprocessing
模块在单独的CPU中完成的。这些并行进程由启动时的主进程生成。如果我希望通过QuickFix
以任何方式与市场互动,我必须在主要流程中执行此操作,因此必须通过管道传输来自子流程的任何命令(例如,输入订单)一个mp.Queue
对象,我们将在执行前调用Q
)到主进程。
这引发了监控Q
的问题,这必须在主流程中完成。我无法使用Q.get()
,因为此方法会阻止,我的整个主流程将会挂起,直到Q
中显示某些内容。为了减少延迟,我必须经常检查Q
,每秒50次。我一直在使用apscheduler来执行此操作,但我一直收到警告错误,指出错过了运行时。这些错误是一个严重的问题,因为它们阻止我轻松查看重要信息。
因此我重构了我的应用程序,使用MestreLion发布的代码作为this question的答案。这对我有用,因为它从主进程启动一个新线程,并且它不会打印错误消息。但是,我担心这将导致令人讨厌的问题。
我知道python中的Global Interpreter Lock(这就是我开始使用multiprocessing
模块的原因),但我并不是真的理解它。由于我的应用程序的高频特性,我不知道Q
监视线程和消耗大量传入消息的主进程是否会竞争资源并相互减慢速度。
我的问题:
我可能在这种情况下遇到麻烦吗?
如果没有,我可以使用现有方法添加更多监控线程,还可以吗?至少还有两件我想高频率监控的事情。
感谢。
答案 0 :(得分: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可能会或可能不会影响性能。测量它。
答案 1 :(得分:0)
在不了解您的情况的情况下,很难说出具体的内容。你的问题表明,线程大部分时间是通过<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
等待的,所以GIL不是问题。进程间通信可能会更早地导致问题。你可以考虑使用某种TCP套接字切换到另一种协议。然后,您可以使用get
而不是线程来更有效地编写调度程序,因为线程也很慢且占用资源。 select
是一个系统函数,允许同时监视多个套接字连接,因此它可以通过大量连接进行非常高效的扩展,并且几乎不需要用于监视的CPU功率。