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

如何在poll、libev、libuv事件循环中运行libserialport?

问题描述

我正尝试将libserialport库集成到支持poll、libev和libuv的解决方案中。用libev或libuv时,可以轻松从libserialport获取串口文件描述符(fd)并监听,示例代码如下:

uv_poll_init(loop, &poller, serial_port_fd);
uv_poll_start(&poller, UV_READABLE /*| UV_PRIORITIZED*/, cb);

但我不知道如何在基于poll的默认循环中实现相同功能,现有主循环示例如下:

while(!interrupted){
    interrupted = service_one_loop();
    //// 此处需添加poll(serial_port_fd)代码并调用串口回调函数
}

另外想了解是否有其他实现方式,比如下面这种轮询非阻塞读取的写法是否可行:

while(!interrupted){
    interrupted = service_one_loop();
    read_size = sp_nonblocking_read(machine_port, read_buffer, read_buffer_size);
    if (read_size >= 0) {
        cb();
    }
}
解决方案

方式一:整合poll系统调用到现有循环

你可以把串口fd加入poll监听集合,在循环中先通过poll等待事件,再处理业务逻辑和串口事件:

#include <poll.h>

struct pollfd fds[1];
int timeout = 10; // 可根据需求调整超时时间,单位ms,0为非阻塞,负数为永久阻塞

// 初始化poll监听配置
fds[0].fd = serial_port_fd;
fds[0].events = POLLIN; // 监听串口可读事件

while(!interrupted){
    // 等待事件触发
    int ret = poll(fds, 1, timeout);
    
    if (ret > 0 && (fds[0].revents & POLLIN)) {
        // 串口有数据可读,执行回调
        cb();
    }
    else if (ret == -1) {
        // 处理poll错误,比如被信号中断
        if (errno != EINTR) {
            // 这里可以添加错误处理逻辑
            break;
        }
    }
    
    interrupted = service_one_loop();
}

方式二:基于libserialport的非阻塞轮询(你提到的写法优化版)

你给出的轮询写法是可行的,但需要优化细节避免无效回调和CPU空转:

while(!interrupted){
    interrupted = service_one_loop();
    
    // 先等待串口就绪,避免频繁调用read浪费CPU
    int wait_ret = sp_wait(machine_port, 10); // 10ms超时
    if (wait_ret == SP_OK) {
        ssize_t read_size = sp_nonblocking_read(machine_port, read_buffer, read_buffer_size);
        if (read_size > 0) {
            // 只有读到有效数据时才调用回调
            cb();
        }
        else if (read_size == 0) {
            // 处理串口连接关闭的情况
        }
    }
    // wait_ret为SP_ERR_TIMEOUT时直接跳过,当前无数据可读
}

这种方式完全基于libserialport的API实现,不需要直接操作文件描述符,更贴合库的设计逻辑。

内容的提问来源于stack exchange,提问作者amit.user105387

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:36:23