带epoll和线程的套接字服务器

时间:2011-11-28 13:24:53

标签: c multithreading sockets pthreads epoll

我正在尝试在C中为Collaborative实时编辑器http://en.wikipedia.org/wiki/Collaborative_real-time_editor创建套接字服务器,但我不知道它的最佳服务器架构是什么。

首先,我试图使用select作为套接字服务器,但在那之后,我正在阅读关于epoll的内容,现在我认为epoll是最好的选择,因为客户端将发送用户将写的每个字母textarea,到服务器,所以服务器将有一大堆数据要处理。

另外,我想使用epoll的线程,但我不确切知道如何使用它们。我想使用线程,因为我认为最好在目标机器上使用2个或所有CPU。

我的计划是

  • 在服务器启动时创建2个线程

  • 第一个主题将分析新客户并准备阅读或发送

  • 第二个线程将具有从/向客户端读取和发送数据的作业

问题是这2个线程将使用while(1)和epoll_wait。

我的问题是,这是一个使用epoll与线程的良好服务器架构吗?如果没有,我有什么选择?

编辑:我无法使用 libevent libev 或其他库,因为这是一个大学项目,我不允许使用外部库。

3 个答案:

答案 0 :(得分:5)

我认为你正试图过度设计这个问题。 Linux中的epoll体系结构适用于有数千个并发连接的情况。在这些情况下,定义pollselect系统调用的方式的开销将是服务器的主要瓶颈。使用pollselectepoll的决定取决于连接数,而不是数据量。

对于你正在做的事情,看起来好像编辑系统中的人类在你打几十个并发编辑后会疯狂。使用epoll可能会让你发疯;他们通过API发挥一些技巧来挤出额外的性能,你必须非常小心地处理你从通话中得到的信息。

这种应用程序听起来像是网络I / O绑定而不是CPU绑定。我会首先尝试将其编写为poll的单线程服务器。当您收到新文本时,如有必要,请为您的客户端缓冲它,然后在套接字接受write调用时将其发送出去。使用非阻塞I / O;您要阻止的唯一呼叫是poll呼叫。

如果您在收到数据后对数据进行大量处理,但在将数据发送回客户端之前,则可以从多线程中受益。首先编写单线程版本,然后编写CPU限制(使用top检查)并且大部分CPU时间花在执行数据处理的函数中(使用gprof检查) ,添加多线程来进行数据处理。

如果需要,可以在程序中使用管道或Unix域套接字进行不同线程之间的通信---这样,主线程中的所有都可以由事件驱动和处理通过poll。或者,使用此模型,您甚至可以使用fork而不是多个线程的多个进程。

答案 1 :(得分:2)

您可能需要考虑使用libevlibevent之类的内容,而不是编写自己的事件处理实现。这些为您提供了一个跨平台的事件处理程序,它将使用任何适当的(selectpollepollkqueue或其他任何东西),最有可能在比两个线程将工作交给另一个更低的开销。

答案 2 :(得分:2)

开始使用libeventlibev并按照他们的示例操作。有很多例子 - 不要试图在这里发明任何新东西