您好我正在使用TCP在C语言中编写Linux服务器。
服务器必须处理多个连接(大约5000个连接)。 5000是最大值,但平均值应该是大约500-1000。
我想知道什么是更好地用于处理客户端连接和监听。如果最好为每个客户端使用一个线程或使用select()
函数。
1)线程 - 每个客户端都有自己的线程。线程正在侦听客户的请求并处理它。
选择功能 - 一个带有select的循环,其中所有请求都在处理中。 (类似于这个http://www.binarytides.com/multiple-socket-connections-fdset-select-linux/)
如果我使用线程,则需要大量内存和CPU性能。因此,我更喜欢使用select但我不确定select是否可以处理这么多连接,如果它不会减慢来自服务器的响应(存在必须通过客户端套接字的循环)。那么对这么多客户使用select是否可以呢?
我正在寻找我的答案但是,我还没有找到它,或者我只是不知道该搜索什么。所以请不要生气。
答案 0 :(得分:5)
通常,线程非常昂贵:每个线程都需要其调用堆栈(通常为兆字节)并在调度程序中使用任务。所以常见的建议是最多有几十个线程(可能使用一些thread pool)。可能一百个线程可能是合理的(在一些功能强大的服务器上),但是数千个线程可能不合理:即使是空闲线程也有些昂贵。
所以我建议使用像poll(2)这样的多路复用调用(优于select
,它通常对文件描述符的数量有一个硬编码限制,内置大小为fd_set
) 。您可以另外使用线程池来提供活动连接(或请求)。
实际上,你所指的是C10K problem。您也可以使用epoll(7)。
多个event loop图书馆提供了一些有用的基础架构:来自GTK的libev,libevent,Glib,...
顺便说一下,您可以使用混合方法:使用线程池的进程池(可能在不同的计算机上运行)。请注意,某些编译器提供split stacks,goroutines的Go language旨在启用许多“green threads”。