【问题标题】:polling file descriptor轮询文件描述符
【发布时间】:2010-08-31 11:52:06
【问题描述】:

对于基于 MIPS 的嵌入式平台,我正在实现一个小程序来轮询 GPIO,即我正在使用芯片供应商的用户级 GPIO 库,它具有基本功能(打开 /dev/gpio、读取、写入引脚等)。设计很简单:

int gpio_fd;
fd_set rfds;

gpio_fd = gpio_open(...);

while (1) {
    FD_ZERO(&rfds);
    FD_SET(gpio_fd, &rfds);

    if (select(gpio_fd + 1, &rfds, NULL, NULL, NULL) > 0) {
        if (FD_ISSET(gpio_fd, &rfds)) {
            /* read pins and similar */
        }
    }
}

但是我面临一个严重的问题 - 这个应用程序在运行时以“&”结尾,即把它放在后台,消耗 99% 的 CPU,这显然是因为紧密的循环,但我观察到类似的方法许多网络代码,它运行良好。

我是否遗漏了什么,会不会是 gpio 库的缺陷?

实际上,只需一个“while(1) ;”就可以达到同样的效果。这可能是内核的“自然”行为吗?

谢谢。

【问题讨论】:

    标签: linux embedded-linux


    【解决方案1】:

    select 调用应该阻塞,直到文件描述符可读为止。

    可能发生的情况是设备驱动程序不支持select 调用,因此它立即退出而不是阻塞。

    另一种可能性是对gpio_open 的调用实际上并没有给你一个真正的Unix 文件描述符。如果那是open("/dev/gpio", O_RDWR) 或类似的东西,我会更加相信它。

    【讨论】:

    • 我刚刚浏览了 gpio 设备驱动程序并没有找到“轮询/选择”实现。我认为您的假设是正确的,谢谢您的提示!
    • @Mark - 可能没有特定的实现,只是设备驱动程序向操作系统发出信号表明它是可读的某种方式。如果我对 Linux 设备驱动程序了解更多,我可以给出更具体的建议。我确实知道有些文件描述符类型没有实现 poll/select 对它们起作用的任何方式。例如引用实际磁盘文件的文件描述符。
    • 我刚刚认为 'select' 可能故意未在 GPIO 库中实现,恕我直言 gpio 文件句柄始终准备好,与例如套接字不同。你会说什么?
    • @Mark - 嗯,这对我来说很有意义。我只是讨厌在不确定的情况下得出结论。您可以检查的一件事是是否曾经执行过 /* read pins and similar */ 代码。如果不是,那么肯定会发生一些有趣的事情,因为 select 没有设置任何位就返回了。
    • 我最终在主循环中使用了 usleep(),它完成了这项工作 - 程序现在不会消耗那么多 CPU。我想我会坚持一段时间,只要它有效:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多