Linux上使用Python3.x的多处理生产者消费者
下面的代码模拟生产者和消费者模型,该模型将从外汇经纪人FXCM收集数据并写入数据库。 每个生产者进程都将与代理建立基于会话的连接 生产商和消费者都将无限期地运行,直到“毒丸”被放入队列,这发生在营业结束时(星期五22:00)。我省略了代码的这一部分,因为它与问题无关。我能找到的所有示例似乎都产生了一个进程,在短时间内做一些工作,然后Linux上使用Python3.x的多处理生产者消费者,python,multiprocessing,python-multiprocessing,producer-consumer,Python,Multiprocessing,Python Multiprocessing,Producer Consumer,下面的代码模拟生产者和消费者模型,该模型将从外汇经纪人FXCM收集数据并写入数据库。 每个生产者进程都将与代理建立基于会话的连接 生产商和消费者都将无限期地运行,直到“毒丸”被放入队列,这发生在营业结束时(星期五22:00)。我省略了代码的这一部分,因为它与问题无关。我能找到的所有示例似乎都产生了一个进程,在短时间内做一些工作,然后join()返回到父进程。像这个 如上所述,producer将无限期运行,原因是登录并创建与代理的会话大约需要3秒钟 当运行下面的代码时,您将看到队列积压,尽管在运行
join()
返回到父进程。像这个
如上所述,producer将无限期运行,原因是登录并创建与代理的会话大约需要3秒钟
当运行下面的代码时,您将看到队列积压,尽管在运行真正的代码时这似乎是最糟糕的
不确定是否相关,但会话是使用API编写的,API是用C++编写的,使用Boosi.
问题是消费者从队列中get()
项目花费的时间太长,我想知道这个模型是否是处理这种类型开发的正确方法
多谢各位
示例代码
from multiprocessing import Process, Queue, cpu_count
from datetime import datetime, timedelta
import numpy as np
import time
def dummy_data(dtto):
dates = np.array(
[dtto - timedelta(days=i) for i in range(300)])
price_data = np.random.rand(len(dates),5)
return np.concatenate(
(np.vstack(dates),price_data), axis=1)
def get_bars(q2, ms, symbol, dtfm, dtto, time_frame):
stop_date = dtfm
while dtto > stop_date:
data = dummy_data(dtto)
dtfm = data[-1,0]
dtto = data[0,0]
q2.put((symbol, dtfm, dtto))
# Switch to date
dtto = dtfm
def producer(q1,q2):
# client = fx.Client(....)
client = 'broker session'
while True:
job = q1.get()
if job == None:
break
sym, dtfm, dtto, tf = job
# Get price data from broker
get_bars(q2, client, sym, dtfm, dtto, tf)
q2.put(None)
def consumer(q2):
while True:
bars = q2.get()
if bars == None:
break
print(q2.qsize(), bars[0], bars[1], bars[2]) # write to db
q1, q2 = Queue(), Queue()
# instruments = client.get_offers()
# instruments = ['GBP/USD', 'EUR,USD',...]
instruments = range(63) # 62 dummy instruments
# Places jobs into the queue for each symbol
for symbol in instruments:
q1.put((symbol,
datetime(2000,1,14,22,0),
datetime(2018,1,14,22,0),
'D1'))
# Setup producers and consumers
pp, cp = range(6), range(2)
pro = [Process(target=producer, args=(q1, q2,)) for i in pp]
con = [Process(target=consumer, args=(q2,)) for i in cp]
for p in pro: p.start()
for p in con: p.start()
# This is just here to stop this script and does not
# exist in the real version
for i in pp: q1.put(None)
for p in pro: p.join()
for p in con: p.join()
print('stopped')
multiprocessing.Queue.get()
的糟糕性能是一个已知的问题(关于Stackoverflow也有几个问题,但没有一般有用的答案)
哪一种表示你应该考虑另一个模型。您可以看到与此相比,有多少进程创建开销;根本不要使用永久运行的流程,而是在数据准备就绪后立即启动流程。当您这样做时,当您的进程分叉时,您的子进程将收到一个内存中的数据副本。这会增加进程创建开销,但会删除队列。您至少可以考虑这一点,因为您的用户写入数据库,不需要向父级报告任何内容。p> Python是一种很棒的语言,但在并行处理方面,它的性能并不是最好的
+ 1“这意味着你应该考虑另一个模型。”我已经做到了。我一直依赖于pythons的多处理能力,而不是按照单独的脚本来考虑,并允许操作系统来处理它。谢谢你的叫醒电话。