c tcp服务器与套接字多路复用:使用select时锁定读写器集?

时间:2013-01-19 17:24:49

标签: multithreading select tcp

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

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中的套接字?这是正确的方法还是这种方法没有任何性能改进?

1 个答案:

答案 0 :(得分:1)

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

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

  • 将用于接受连接的套接字放入与接受的连接相同的阵列中,以便在单个select()调用中使用。除非绑定到不同的网络接口,否则使用多个线程不会使程序运行得更快。
  • 如果您正在处理传入的数据,这是第二个线程变得有用的地方。一般来说,你有网络接口卡,CPU,硬盘等资源。每个资源有一个线程是有用的,即一个用于处理网络IO(接收请求,发送响应),第二个用于处理实际请求。如果您有多个核心,您还可以使用多个线程来处理请求,前提是这是一个CPU绑定的任务。如果所有这些请求都是从单个硬盘提供图片,则使用多个线程进行请求将不会为您提供任何额外的性能。