You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅地取消libgpiod中的gpiod_line_event_wait调用?

问题:libgpiod GPIO监听线程的优雅退出

我需要创建一个监听GPIO芯片线路事件的工作线程,并且能正常停止它。当前的实现方式如下:

std::jthread([this]() {
    gpiod_line_event event;
    while (is_running) {
        gpiod_line_event_wait(line, NULL);
        gpiod_line_event_read(line, &event);
        if (event.event_type == GPIOD_LINE_EVENT_RISING_EDGE) {
            std::cout << "GPIOD_LINE_EVENT_RISING_EDGE\n";
        } else if (event.event_type == GPIOD_LINE_EVENT_FALLING_EDGE) {
            std::cout << "GPIOD_LINE_EVENT_FALLING_EDGE\n";
        }
    }
});

但线程会卡在gpiod_line_event_wait调用中无法退出。我试过关闭芯片、释放线路、设置线路值,都没有效果。注意到常量GPIOD_CTXLESS_EVENT_POLL_RET_STOP,但不清楚它的用途和用法。

另外,我知道可以给gpiod_line_event_wait加超时参数定期检查退出条件,但希望有其他更优雅的解决方案。


解决方案:通过文件描述符+ppoll实现可中断监听

libgpiod提供了gpiod_line_request_get_fd函数,能获取线路请求对应的文件描述符。我们可以结合一个用于触发停止信号的通道(比如pipe),通过ppoll同时监听这两个文件描述符,当需要停止线程时,向通道写入数据即可唤醒ppoll,进而退出线程。

示例实现代码:

int wait_until(int fd, int channel, int64_t timeout_ns)
{
        struct pollfd pfds[2];
        int ret;

        memset(&pfds, 0, sizeof(pfds));
        pfds[0].fd = fd;
        pfds[0].events = POLLIN | POLLPRI;
        pfds[1].fd = channel;
        pfds[1].events = POLLIN | POLLERR;

        ret = poll_fds(pfds, 2, timeout_ns);
        if (ret >= 1 && pfds[1].revents != 0)
                return 2;
        return ret;
}

static int
poll_fds(struct pollfd *pfds, uint8_t len, int64_t timeout_ns)
{
        struct timespec ts;
        int ret;

        if (timeout_ns >= 0) {
                ts.tv_sec = timeout_ns / 1000000000ULL;
                ts.tv_nsec = timeout_ns % 1000000000ULL;
        }

        ret = ppoll(pfds, len, timeout_ns < 0 ? NULL : &ts, NULL);
        if (ret < 0)
                return -1;
        else if (ret == 0)
                return 0;

        return 1;
}

使用说明

  • 先创建一个pipe作为停止信号通道,线程中监听pipe的读端
  • 调用gpiod_line_request_get_fd获取GPIO线路的文件描述符
  • 在线程循环中调用wait_until替代gpiod_line_event_wait
  • 当需要停止线程时,向pipe的写端写入任意数据,wait_until会返回2,此时即可退出循环

内容的提问来源于stack exchange,提问作者alajnabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:25:19