在linux服务器上处理多个客户端连接的正确方法是啥

Posted

技术标签:

【中文标题】在linux服务器上处理多个客户端连接的正确方法是啥【英文标题】:What is the proper way to handle multiple clients connections on linux server在linux服务器上处理多个客户端连接的正确方法是什么 【发布时间】:2015-01-20 15:26:13 【问题描述】:

您好,我正在使用 TCP 用 C 语言在 linux 上编写服务器。 服务器必须处理多个连接(最多大约 5000 个)。 5000 是最大值,但平均值应该在 500 - 1000 左右。 我想知道在处理客户端连接和监听时使用什么更好。如果最好为每个客户端使用一个线程或使用select()函数。

1) 线程 - 每个客户端都有自己的线程。该线程正在监听客户端的请求并进行处理。

Select 函数 - 一个带有 select 的循环,所有请求都在其中处理。 (类似于http://www.binarytides.com/multiple-socket-connections-fdset-select-linux/)

如果我要使用线程,它将需要大量内存和 cpu 性能。因此,我更喜欢使用 select 但我不确定 select 是否可以处理这么多的连接,以及它是否不会减慢来自服务器的响应(存在必须通过客户端套接字的循环)。那么这么多客户可以使用 select 吗?

我一直在寻找我的答案,但是我没有找到它,或者我只是不知道要搜索什么。所以请不要难过。

【问题讨论】:

【参考方案1】:

一般来说,线程是相当昂贵的:每个线程都想要它的调用堆栈(通常是兆字节)并在调度程序中消耗一个任务。所以常见的建议是最多有几十个线程(也许使用一些thread pool)。可能一百个线程可能是合理的(在一些强大的服务器上),但数千个线程可能不合理:即使是空闲线程也有点昂贵。

所以我建议使用像poll(2) 这样的多路复用调用(优于select,后者通常对文件描述符的数量有硬编码限制,内置大小为fd_set)。您还可以使用线程池来服务活动连接(或请求)。

其实你指的就是C10K problem。你也可以使用epoll(7)。

几个event loop 库正在提供一些有用的基础架构:libev、libevent、Glib 来自 GTK,...

顺便说一句,您可以采用混合方法:使用线程池的进程池(可能在不同的机器上运行)。

请注意,一些编译器提供split stacks,而Go language 的goroutines 旨在启用许多“green threads”。

【讨论】:

非常感谢您的回答。这很有帮助:) 我不知道 epoll。我将使用epoll。 您考虑过使用libev 吗? 是的,但我没有这样的经验。也许以后。我不想让它复杂化。我从来没有编程过服务器,所以我必须首先学习一些东西...... 如果你自己做所有的事情,你可能会比使用一些成熟的图书馆犯更多的错误和花费更多的时间。是为了娱乐和学习,还是为了认真工作? 这是一个学校项目:)

以上是关于在linux服务器上处理多个客户端连接的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

linux下,socket服务器和客户端TCP方式建立了连接,如何使它们之间相互发送消息?

serversocket 类如何在同一个端口上服务多个客户端连接?

Jetty Websockets - 在处理不可靠的连接时正确发送异步消息

Jetty Websockets - 在处理不可靠的连接时正确发送异步消息

Linux高性能服务编程(I/O复用)

处理 TCP 故障的正确机制是啥?