linux选择性能场景

时间:2012-12-18 16:16:17

标签: c linux tcp

我写了一个简单的tcp服务器应用程序,其中我的fd_set for read包含连接套接字描述符。服务器应用程序只要收到消息就会发送一个ACK。客户端应用程序仅在从服务器收到ACK后才发送下一条消息。

// timeval == NULL
select(maxfd, &read_set, NULL, NULL, NULL)

当我这样做时,性能大约是3K消息/秒。发送确认和从客户端接收响应之间的延迟为0.3毫秒。

// tm.tv_sec=0 and tm.tv_usec=0
select(maxfd, &read_set, NULL, NULL, tm)

但如果我这样做,性能将达到8K消息/秒,延迟降至0.18ms。

在后一种情况下,select成为民意调查。有人可以解释为什么后一种情况比第一种情况好得多吗?

3 个答案:

答案 0 :(得分:2)

可能的答案

当超时为零时,当没有可用数据时,select()调用立即返回。这允许您忙于等待套接字轮询,主动烧毁CPU周期直到数据到达。

当超时为NULL时,如果没有数据,您的进程将在等待数据可用的WAIT_INTERRUPTIBLE状态下进入休眠状态。这导致至少两个上下文切换的惩罚,一个远离您的进程,一个回到它时数据可用。这样做的好处是您的进程会放弃CPU并允许其他进程运行。

这就像比较spinlocks and semaphores。自旋锁“旋转”CPU等待条件,而信号量产生CPU。自旋锁性能更高,但它们会占用CPU,因此它们只能用于非常短的等待时间。信号量与其他进程更加协作,但由于额外的上下文切换,它们会产生明显的开销。

答案 1 :(得分:0)

它不会回答你的问题,但如果你真的想要表现良好,并且收到的信息率非常高,你可以试试:

  • 以O_NONBLOCK打开
  • 首先尝试阅读
  • 如果读取失败并显示错误代码EAGAIN或EWOULDBLOCK,请使用timeval == NULL
  • 进行选择
  • 处理数据

答案 2 :(得分:-2)

select(2)的手册页

  

超时是之前经过的时间量的上限   select()返回。如果时间结构的两个字段都为零,   然后select()立即返回。 (这对于轮询非常有用。)如果   timeout为NULL(无超时),select()可以无限期阻塞

增加的重点是我的。如果您担心延迟,请查看epoll(4)