0

我用 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 使用率几乎为零,并且处理请求不需要时间。

这是我不明白的:

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

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

4

1 回答 1

0

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

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

描述

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

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

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

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

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

timeout 参数指定 poll() 将阻塞的最小毫秒数。(这个时间间隔会向上取整到系统时钟粒度,内核调度延迟意味着阻塞时间间隔可能会出现少量溢出。) timeout 中指定负值意味着无限超时。将超时指定为零会导致 poll() 立即返回,即使没有准备好文件描述符。

——摘录结束

不知何故,与发布的代码相比,我看不出poll()应该如何调用和它的作用之间的关系。

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

于 2015-10-28T23:31:16.850 回答