使用select,epoll或kqueue提供大文件

时间:2010-03-29 17:40:10

标签: select nginx epoll kqueue

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

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

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

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

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:4)

最简单的方法是为每个请求创建一个线程,但它肯定不是最可伸缩的方法。我认为目前基本上所有高性能Web服务器都使用各种基于epoll(Linux),kqueue(BSD)或IOCP(Windows)的异步方法。

由于您未提供有关性能要求的任何信息,并且因为所有非线程方法都需要重构您的应用程序以使用这些通常复杂的异步技术(如C10K article中所述,以及那里,现在你最好的选择就是使用线程方法。

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

答案 2 :(得分:2)

对于背景,阅读http://www.kegel.com/c10k.html

可能很有用

答案 3 :(得分:0)

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