Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Django plus芹菜/RabbitMQ,带用于C套接字模块的线程_Multithreading_Concurrency_Celery_Gevent_Eventlet - Fatal编程技术网

Multithreading Django plus芹菜/RabbitMQ,带用于C套接字模块的线程

Multithreading Django plus芹菜/RabbitMQ,带用于C套接字模块的线程,multithreading,concurrency,celery,gevent,eventlet,Multithreading,Concurrency,Celery,Gevent,Eventlet,我们有一个Django webapp,它使用芹菜4.x异步运行任务。主要任务需要Django/Cellery代码来执行与20-100台其他服务器的网络通信操作。我们向其他服务器发送的每个请求都是相同的,即用户向Django发送一个命令,Django然后告诉芹菜向其他20-100个服务器发送完全相同的命令。问题是,对于芹菜的基本配置,如果我们有4个工人,那么芹菜一次只能与4台服务器通信。为了解决这个问题,我们尝试使用芹菜和gevent。然而,gevent使用协同路由而不是全线程,对于我们的网络操作

我们有一个Django webapp,它使用芹菜4.x异步运行任务。主要任务需要Django/Cellery代码来执行与20-100台其他服务器的网络通信操作。我们向其他服务器发送的每个请求都是相同的,即用户向Django发送一个命令,Django然后告诉芹菜向其他20-100个服务器发送完全相同的命令。问题是,对于芹菜的基本配置,如果我们有4个工人,那么芹菜一次只能与4台服务器通信。为了解决这个问题,我们尝试使用芹菜和gevent。然而,gevent使用协同路由而不是全线程,对于我们的网络操作,我们使用我们自己的用C编写的python模块。换句话说,我们不使用可以通过猴子补丁的python套接字或请求模块

因此,我们想做以下几点。为了便于讨论,假设我们的C通信模块被称为“cnet”。如果我们有20台其他服务器必须与之通信,我们将有一个芹菜任务功能,它可以执行以下操作:

# This uses our cnet module (written in C) to connect to a single other server
def connect_to_server(server, user_data):
    response=cnet.execute_request(server,user_data)
    output=do_something_with_response(response)
    return output

@task
def send_something_important_to_all_servers(dest_servers, user_data):
    for server in dest_servers:
        t = create new thread to run connect_to_server(server, user_data)
        t.start()
    wait/join on all threads
    return
关于我们如何实施这一点,我有一些问题。最初,我们使用预工作池和多个工作人员,每个工作人员一个任务,但无法扩展。接下来,我们使用了gevent,但我们没有做任何特殊的事情,只是用4名工人推出了芹菜,每个工人都有大量的小菜,就像这里所做的一样: 当然,这仍然显示出同样的问题,如果我们有4个工人,那么我们在同一时间只能运行4个东西


现在我已经读到,我们可以使用eventlet池,它有一个叫做tpool的东西,我们可以在任务中使用它来生成多个线程。文档中说,这对于我们使用本机C网络模块的情况尤其有用,因为该模块不能通过猴子补丁。所以这是我们最好的方法。ie将eventlet与tpool一起使用?在我们的情况下,是否有任何理由使用gevent而不是eventlet,如果有,是否有一个gevent等价于tpool?有人举过芹菜代码的例子来处理这样的情况吗,即使用非本机网络代码,不能通过猴子补丁?

您最好的选择是在C中进行多路复用,将其作为一个处理所有请求的单一函数呈现给芹菜。在C中也有多种方法可以实现这一点,OS线程只是其中之一。选择你最了解的,你最喜欢的

Eventlet tpool将正常工作,请注意,默认情况下其大小仅为20,您可能希望增加

如果从C模块内部使用python套接字模块,猴子补丁仍然可以工作。这可能是最便宜、最快的方法


更新:
eventlet.tpool()。它并没有明确地写在文档中,因为任何阻塞API都会破坏库的功能。任何数量的协同程序(小于或大于tpool大小)都将按预期工作。Tpool size只限制同时运行的操作系统线程的数量。

此时,我们无法在C中进行多路复用,在一个非常复杂的C程序中需要做太多的工作。我很确定C代码中没有使用python套接字。因此,听起来tpool是一个不错的选择。但是你能帮我理解一下吗?tpool.execute是否会以这样一种方式阻塞,它会让其他协程同时运行,这样所有调用tpool.execute的协程都可以同时运行(至少有20个)?文档中没有很好地解释这一点。可能没有使用python套接字,但这是一个简单的搜索和替换更改。Tpool的产量和其他所有产品一样。gevent中是否有相应的模块?我可以用gevent.something来代替eventlet.tpool吗?@Marc我不知道,但是你当然可以将eventlet/greenpool.py复制到你的项目中。适应应该像
s/eventlet/gevent/
一样简单或接近它。