0

我的服务器使用非阻塞套接字多路复用。我想使用一个线程来接收传入的连接并处理输入,并使用另一个线程来通过套接字发送数据。它看起来像这样:

reader_worker(...)
{
    ...
    select(fd_max+1, &read_set, NULL, NULL, NULL);
    ...
}

writer_worker(...)
{
    ...
    select(fd_max+1, NULL, &write_set, NULL, NULL);
    ...
}

由于我不想错过传入的连接,我可以想象在单独的线程中接收和发送会更好。我是否必须锁定可能在 read_set 和 write_set 中的套接字?这是正确的方法还是这种方法没有任何性能改进?

4

1 回答 1

1

如果您在一个线程中执行此操作,您将不会错过任何传入连接。即使您有大量数据要发送或接收,send() 或 recv() 调用的延迟也取决于网络堆栈中本地缓冲区的大小,因此您将很快回来接受传入的连接。

不过有两件事,我不确定您的代码示例:

  • 将用于接受连接的套接字放入与接受的连接相同的数组中,以便在单个 select() 调用中使用。除非您绑定到不同的网络接口,否则使用多个线程不会让您的程序运行得更快。
  • 如果您正在处理传入的数据,这就是第二个线程变得有用的地方。通常,您拥有网络接口卡、CPU、硬盘等资源。每个资源有一个线程很有用,即一个处理网络 IO(接收请求,发送响应),另一个处理实际请求。如果您有多个内核,您还可以使用多个线程来处理请求,前提是这是一个 CPU 密集型任务。如果这些请求所做的只是从单个硬盘提供图片,那么使用多个线程处理请求不会给您带来任何额外的性能。
于 2013-01-19T22:28:52.457 回答