使用select、epoll或kqueue服务大文件

使用select、epoll或kqueue服务大文件,select,nginx,epoll,kqueue,Select,Nginx,Epoll,Kqueue,Nginx使用epoll或其他多路复用技术select来处理多个客户端,即不像apache那样,它不会为每个请求生成新线程 我尝试在我自己的测试程序中使用select复制相同的内容。我可以通过创建一个非阻塞套接字并使用select来决定服务哪个客户端来接受来自多个客户端的连接。我的程序只是简单地将他们的数据回显给他们。对于每个客户端传输一些字节的小数据来说,它工作得很好 当我需要通过连接将一个大文件发送到客户端时,就会出现问题。由于我只有一个线程为所有客户端提供服务,直到我完成文件的读取并将其写

Nginx使用epoll或其他多路复用技术select来处理多个客户端,即不像apache那样,它不会为每个请求生成新线程

我尝试在我自己的测试程序中使用select复制相同的内容。我可以通过创建一个非阻塞套接字并使用select来决定服务哪个客户端来接受来自多个客户端的连接。我的程序只是简单地将他们的数据回显给他们。对于每个客户端传输一些字节的小数据来说,它工作得很好

当我需要通过连接将一个大文件发送到客户端时,就会出现问题。由于我只有一个线程为所有客户端提供服务,直到我完成文件的读取并将其写入套接字为止,我无法继续为其他客户端提供服务


这个问题是否有一个已知的解决方案,或者最好为每个这样的请求创建一个线程?

对于后台来说,这可能是有用的阅读

最简单的方法是为每个请求创建一个线程,但它肯定不是最具伸缩性的方法。我认为现在基本上所有的高性能web服务器都使用各种异步方法,这些异步方法都是构建在诸如epoll Linux、kqueue BSD或IOCP Windows之类的东西上的

由于您没有提供有关性能要求的任何信息,而且由于所有非线程方法都需要重新构造您的应用程序,以使用中描述的这些通常非常复杂的异步技术以及从中找到的其他技术,因此现在您最好的选择就是使用线程方法


如果您需要更多信息,请用具体的性能要求和其他相关数据更新您的问题。

使用select时,您不应立即发送整个文件。例如,如果您正在使用sendfile来执行此操作,它将一直阻止,直到发送完整个文件。而是使用一个小的缓冲区,一次向每个客户机发送一点数据。然后使用select确定套接字何时再次准备好写入,并发送更多数据,直到所有数据都已发送。这将允许您并行处理多个客户端。

我认为您正在使用回调处理单个连接。它不是这样设计的。您的回调必须处理您计划服务的数千个连接,即从作为参数获得的文件描述符的数量,您必须通过读取全局变量知道如何处理该客户机,或者读取或发送,或者。。。随便