Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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 在同一套接字上进行多进程epoll时,为什么cpu不平衡?_Multithreading_Sockets_Linux Kernel_Epoll - Fatal编程技术网

Multithreading 在同一套接字上进行多进程epoll时,为什么cpu不平衡?

Multithreading 在同一套接字上进行多进程epoll时,为什么cpu不平衡?,multithreading,sockets,linux-kernel,epoll,Multithreading,Sockets,Linux Kernel,Epoll,我有一个接收传入连接的高性能服务器,主进程在tcp端口上侦听/绑定,并将自身分叉给一些工作人员。 工人然后使用epoll监视传入的连接事件,如果事件发生,则尝试接受连接 它工作得很好,但当我计算每个工作人员处理的连接(或每个工作人员消耗的CPU UTIL)时,我发现它根本不平衡 例如: 一个忙碌的工作人员:处理10k连接,消耗20%的CPU; 一个空闲工人:处理300个组件,消耗4%的CPU 我的服务器运行在RHEL6.5操作系统(2.6.32内核)上 有人能在这个问题上帮助我吗 编辑: 为什

我有一个接收传入连接的高性能服务器,主进程在tcp端口上侦听/绑定,并将自身分叉给一些工作人员。 工人然后使用epoll监视传入的连接事件,如果事件发生,则尝试接受连接

它工作得很好,但当我计算每个工作人员处理的连接(或每个工作人员消耗的CPU UTIL)时,我发现它根本不平衡

例如:

一个忙碌的工作人员:处理10k连接,消耗20%的CPU; 一个空闲工人:处理300个组件,消耗4%的CPU

我的服务器运行在RHEL6.5操作系统(2.6.32内核)上

有人能在这个问题上帮助我吗


编辑:

为什么? 在挖掘了一些内核代码(2.6.32.x)之后,我找到了出现平衡的原因

1*MasterProcess:创建并绑定监听套接字
n*WorkerPressure:创建epfd并从master监视侦听套接字

当工作进程epoll_ctl(…,listen_sock,…)时,内核将监视文件添加到epoll结构的rbtree中(@see fs/eventpoll.c ep_insert),并通过回调(ep_ptable_queue_proc)将epoll结构添加到listen_sock的wait_队列中

当新连接传入(SYN_REC)时,侦听套接字的事件已更改,内核将迭代waitqueue,通过epoll给出的回调将事件通知套接字上的所有epoll监视器。回调是ep_poll_回调(@see fs/eventpoll.c),回调将在epoll_wait系统调用时唤醒进程(或线程)wait

侦听套接字的waitqueue序列在notify进程之后不会更改。等待事件的进程将以固定顺序收到通知。与最后一个得到通知的流程相比,提前唤醒的流程应该有更多的连接需要处理。这导致了平衡

修理 1*MasterProcess为所有WorkerProcess创建一个epfd; 2*通过epoll_wait在同一epfd上执行WorkerProcess wait

在本例中,我们在内核级别只有一个epoll结构。当事件发生时,将只调用一个epoll结构的等待回调

epoll结构的唤醒回调是:

static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key)
现在,WorkerProcess的所有boss线程都是在epoll_wait上等待,而ep_poll_回调只会唤醒其中一个线程

当WorkerProcess被epoll唤醒时,它将从wait_队列中移除自身,并在调用epoll_wait时将其自身重新添加到wait_队列的尾部。因此,我们可以逐个唤醒WorkerProcess

没有问题

拥有多个工作人员的目的是让至少一个工作人员可用,即使其他工作人员很忙

但是,当多个工作人员在等待时,由谁获得事件并不重要。进程/线程不会因为运行时间较长而磨损


因为内核不关心,所以没有平衡。您也不应该这样做。

主进程从工作进程池中选择工作进程的依据是什么?主进程不选择工作进程,工作进程在从主进程继承的套接字上侦听。发布一些代码。您可能希望不那么忙的人先到达
epoll()
accept()
,但这是一场比赛,您需要正确地防止输掉比赛,即
accept()
导致EAGAIN/ewoldblock。我很想看看你是如何处理这些事情的。共享epfd是正确的方法,否则只使用select没有任何好处。但请记住,被唤醒的进程是“最后一个调用poll()。因此,如果您有2个进程PID1、PID2和PID2最后调用它,PID2将被唤醒,如果在PID2处理上一个事件时出现新事件,PID1将被调用。。。但是,如果没有事件发生,并且PID2完成,并且再次调用poll(),那么下一个事件将唤醒PID2。这可能会导致流程不平衡。我已经找到了一个解决方案。如果所有工作进程都从主进程继承了epfd,则由它们自己创建一个(epoll_cteate)。所有工作人员几乎都会处理相同数量的请求。我必须关心这个问题,因为每个进程并发处理的连接平衡对我的服务器来说非常重要。
static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key)