Linux上使用Python3.x的多处理生产者消费者

Linux上使用Python3.x的多处理生产者消费者,python,multiprocessing,python-multiprocessing,producer-consumer,Python,Multiprocessing,Python Multiprocessing,Producer Consumer,下面的代码模拟生产者和消费者模型,该模型将从外汇经纪人FXCM收集数据并写入数据库。 每个生产者进程都将与代理建立基于会话的连接 生产商和消费者都将无限期地运行,直到“毒丸”被放入队列,这发生在营业结束时(星期五22:00)。我省略了代码的这一部分,因为它与问题无关。我能找到的所有示例似乎都产生了一个进程,在短时间内做一些工作,然后join()返回到父进程。像这个 如上所述,producer将无限期运行,原因是登录并创建与代理的会话大约需要3秒钟 当运行下面的代码时,您将看到队列积压,尽管在运行

下面的代码模拟生产者和消费者模型,该模型将从外汇经纪人FXCM收集数据并写入数据库。 每个生产者进程都将与代理建立基于会话的连接

生产商和消费者都将无限期地运行,直到“毒丸”被放入队列,这发生在营业结束时(星期五22:00)。我省略了代码的这一部分,因为它与问题无关。我能找到的所有示例似乎都产生了一个进程,在短时间内做一些工作,然后
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的多处理能力,而不是按照单独的脚本来考虑,并允许操作系统来处理它。谢谢你的叫醒电话。