如何处理poll()而不减慢服务器或浪费CPU?

时间:2015-10-28 20:27:08

标签: c server cpu polling usleep

我在C中使用自制服务器遇到了一个有趣的问题。

主线部分总结如下:

while(donotend==1){
    if (somethingdetected==1){
    //do critical code
    }
    if (poll(structs,numberoffields,x) < 1){continue;}
    //do functions based on poll fields that were filled in
}

我注意到的是poll()决定了输出速度和CPU使用率。

如果我将最后一个参数x(超时值)设置为零,那么仅程序的CPU使用率就高于95%,但是每个服务器的请求都会立即处理。

但是,如果我将x设置为500,那么cpu使用率仍然高于95%,但处理请求需要2秒。

如果我在usleep(500)之前使用poll(),则cpu使用率几乎为零,并且处理请求时不会。

这是我不明白的地方:

为什么轮询不会达到最后一个参数中指定的毫秒数来捕获事件并在找到至少一个时返回而不是总是等待整个毫秒超时?

什么是有效的usleep值?我觉得指定太高的usleep值会导致正常的程序执行锁定,而指定太低的一个不会产生影响。

1 个答案:

答案 0 :(得分:0)

阅读poll()的手册页给出了一个完全不同的参数和参数含义的故事

以下是手册页的相关摘录:

描述

poll()执行类似的任务来选择(2):它等待一组文件描述符中的一个准备好执行I / O.

要监视的文件描述符集在fds参数中指定,该参数是以下形式的结构数组: struct pollfd {     int fd; / *文件描述符 /     短暂的事件; / 请求的活动 /     短暂的复活; / 返回事件* / }; 调用者应在nfds中指定fds数组中的项目数。 字段fd包含打开文件的文件描述符。如果此字段为负,则忽略相应的事件字段,并且revents字段返回零。 (这提供了一种忽略单个poll()调用的文件描述符的简单方法:简单地否定fd字段。)

字段事件是一个输入参数,一个位掩码,用于指定应用程序对文件描述符fd感兴趣的事件。如果将此字段指定为零,则fd将忽略所有事件,并且revents返回零。

字段revents是一个输出参数,由内核填充实际发生的事件。 revents中返回的位可以包括事件中指定的任何位,或POLLERR,POLLHUP或POLLNVAL中的值之一。 (这三个位在事件字段中没有意义,只要相应的条件为真,就会在revents字段中设置。)

如果没有任何事件请求(并且没有错误)发生任何文件描述符,则poll()将阻塞,直到其中一个事件发生。

timeout参数指定poll()将阻止的最小毫秒数。 (此间隔将向上舍入到系统时钟粒度,并且内核调度延迟意味着阻塞间隔可能会超出一小部分。)在超时中指定负值意味着无限超时。指定超时为零会导致poll()立即返回,即使没有准备好文件描述符也是如此。

- 结束摘录

不知何故,与发布的代码相比,我没有看到应该调用poll()的方式与它的作用之间的关系。

也许你可以在你的问题中解决这种关系。