如何将epoll检测到的事件处理成多线程?

问题描述 投票:0回答:1

我们正在使用 epoll 和多线程实现服务器和客户端

一共有5个多线程,会连接100个客户端

主线程要处理客户端的访问请求,让线程为每个客户端的事件工作。

主线程将accepted clients添加到epoll_fd中。

在 pthread_crate(...) 中,我们接收 &epoll_fd 作为一个因子,多线程正在执行 epoll_wait()。

但是,如果当前客户端请求connect(),服务器的其他请求, 所有五个多线程检测事件。

如何防止其他线程处理已经处理过的事件?

不使用 thread_poll.

c multithreading sockets epoll
1个回答
0
投票

在pthread_crate(...)中,我们接收&epoll_fd作为一个因子,多线程正在做epoll_wait()。但是,如果当前客户端请求connect(),其他来自服务器的请求,所有五个多线程检测事件。

这叫雷霆万钧。你应该避免它。

在计算机科学中,当事件发生时,大量等待事件的进程或线程被唤醒,但只有一个进程能够处理该事件,就会出现雷群问题。当进程醒来时,它们将各自尝试处理该事件,但只有一个会获胜。所有进程都将争夺资源,可能会冻结计算机,直到牛群再次平静下来。

为了避免这个问题,你应该让主线程调用epoll_wait()。主线程接受新套接字后,它将套接字传递给其中一个工作线程。

另外,线程池对于服务器来说非常重要。通过维护线程池,服务器可以提高性能并避免由于频繁创建和销毁短期任务的线程而导致的执行延迟。

然后你需要一个方法将新接受的客户端传递给线程池中的工作线程。这叫做生产者-消费者问题。主线程扮演生产者,工作线程扮演消费者。最简单的方法是使用队列来解耦生产者和消费者。主线程将接受的客户端推送到队列的头部。工作线程从队列尾部弹出客户端。当然,您需要在将元素推入/弹出队列时锁定队列。还有其他的派发client给worker的方式,大家自己去探索吧

© www.soinside.com 2019 - 2024. All rights reserved.