我正在尝试在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 或其他库,因为这是一个大学项目,我不允许使用外部库。
答案 0 :(得分:5)
我认为你正试图过度设计这个问题。 Linux中的epoll
体系结构适用于有数千个并发连接的情况。在这些情况下,定义poll
和select
系统调用的方式的开销将是服务器的主要瓶颈。使用poll
或select
与epoll
的决定取决于连接数,而不是数据量。
对于你正在做的事情,看起来好像编辑系统中的人类在你打几十个并发编辑后会疯狂。使用epoll
可能会让你发疯;他们通过API发挥一些技巧来挤出额外的性能,你必须非常小心地处理你从通话中得到的信息。
这种应用程序听起来像是网络I / O绑定而不是CPU绑定。我会首先尝试将其编写为poll
的单线程服务器。当您收到新文本时,如有必要,请为您的客户端缓冲它,然后在套接字接受write
调用时将其发送出去。使用非阻塞I / O;您要阻止的唯一呼叫是poll
呼叫。
如果您在收到数据后对数据进行大量处理,但在将数据发送回客户端之前,则可以从多线程中受益。首先编写单线程版本,然后编写CPU限制(使用top
检查)并且大部分CPU时间花在执行数据处理的函数中(使用gprof
检查) ,添加多线程来进行数据处理。
如果需要,可以在程序中使用管道或Unix域套接字进行不同线程之间的通信---这样,主线程中的所有都可以由事件驱动和处理通过poll
。或者,使用此模型,您甚至可以使用fork
而不是多个线程的多个进程。
答案 1 :(得分:2)
您可能需要考虑使用libev或libevent之类的内容,而不是编写自己的事件处理实现。这些为您提供了一个跨平台的事件处理程序,它将使用任何适当的(select
,poll
,epoll
,kqueue
或其他任何东西),最有可能在比两个线程将工作交给另一个更低的开销。
答案 2 :(得分:2)