0

我正在尝试编写一个能够以 C 语言同时处理多个(超过一千个)客户端连接的服务器。每个连接都旨在完成三件事:

  1. 向服务器发送数据
  2. 服务器处理数据
  3. 服务器返回数据给客户端

我正在使用非阻塞套接字和 epoll() 来处理所有连接,但我的问题是在服务器从一个客户端接收到数据之后的那一刻,并且必须调用一个函数,该函数花费几秒钟来处理它之前的数据返回关闭连接之前必须发送回客户端的结果。

我的问题是,当一个客户端的数据“正在烹饪”时,我可以使用什么范例来继续处理更多连接?

每次我需要调用计算函数时,我一直在研究通过创建线程或进程来实现它的可能性,但我不确定考虑到可能的并发连接数是否可行,那就是为什么我来这里是希望有人在这件事上比我更有经验,可以揭示我的无知。


代码片段:

while (1)
                {
                  ssize_t count;
                  char buf[512];
                  count = read (events[i].data.fd, buf, sizeof buf); // read the data
                  if (count == -1)
                    {
                      /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                      if (errno != EAGAIN)
                        {
                          perror ("read");
                          done = 1;
                        }
                      /* Here is where I should call the processing function before
                         exiting the loop and closing the actual connection */

                         answer = proc_function(buf);
                         count = write (events[i].data.fd, answer, sizeof answer); // send the answer to the client
                         break;
                    }
                    ...

提前致谢。

4

1 回答 1

1

多线程或多进程在某种程度上实现这一点似乎是明智的。多线程或多进程的程度是个问题。

1)您可以完全转储轮询系统并为每个连接使用一个线程/进程。只要该线程想要处理该连接,它就可以停止。然后,您必须决定每次创建/终止一个线程/进程(可能最简单)或拥有一个线程/进程池(可能最快)。

2)您可以有一个用于网络位的线程/进程,并将处理移交给另一个线程。这不太并行,但这确实意味着您至少可以在浏览工作列表时继续处理网络连接。这使您至少可以控制正在处理的处理。以这种方式对传入连接进行优先级排序很容易,而选项 1 可能不会。

3)(可能的 1 和 2)您可以使用异步 I/O 来多路复用连接。您仍然按照与上述 1 和 2 相同的方式进行处理。

您还有线程与进程的问题。线程可能启动得更快,但更难确保数据完整性。流程将更具弹性,但需要它们之间的更多接口。

您还必须决定在线程/进程之间传递数据的方法。对于选项 1,这不是问题,因为您只需将连接传递给线程。选项 2 可能(取决于您的数据是什么)更成问题。您可以使用消息队列来传递消息,但如果您有大量数据要发送共享内存更合适。共享内存对于进程来说是一种痛苦,但对于线程来说很容易(因为所有线程共享相同的内存空间)。

当你达到这个规模时,也会出现性能问题。值得研究这些东西的性能特征。当您处理大量连接时,select 和 poll 等调用规模的差异非常重要。

如果不知道发送和接收的数据是什么,就很难给出可靠的建议。

顺便说一句,这不是一个新问题。几年前,丹·凯格尔( Dan Kegel)有一篇关于它的好文章。它现在已经过时了,但概述仍然很好。不过,您应该研究他讨论的概念的当前技术状态。

于 2013-07-10T14:49:37.450 回答