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

C语言中poll()无法检测jq输出作为stdin的问题咨询

为什么poll()无法识别jq输出作为程序的标准输入?

问题场景

我编写了一个C语言函数,使用poll()检测标准输入是否存在可读数据,代码如下:

#include <stdio.h>
#include <sys/poll.h>

// 其他代码

void check_stdin(){
    struct pollfd fds;
    int ret; 
    fds.fd = 0; 
    fds.events = POLLIN;
    ret = poll(&fds, 1, 10);
    printf("Return value: %d\n", ret);
    if(ret != 1){
        printf("stdin could not be read\n");
    }
}

其中fds.fd=0对应STDIN的文件描述符,fds.events=POLLIN用于检测可读事件,超时时间设置为10毫秒。

执行以下命令:

echo "{\"key\": 1}" | jq .key | ./test_stdin

得到输出:

Return value: 0
stdin could not be read

按预期,当stdin存在可读数据时poll()的返回值应为1,为何jq的标准输出无法被./test_stdin识别为标准输入?

问题根源

核心原因是超时时间设置过短。poll()仅等待10毫秒,而管道上游的jq进程需要完成启动、JSON解析、结果输出这些操作,耗时通常会超过10毫秒。当你的程序调用poll()时,jq还未将数据写入管道,此时标准输入对应的管道读端没有可读数据,poll()就会因超时返回0。

管道是基于缓冲区的通信机制,只有上游进程将数据写入管道缓冲区后,下游进程的poll()才能检测到POLLIN可读事件。10毫秒的等待窗口完全不足以覆盖jq的处理周期。

解决办法

  • 延长单次超时时间:将poll()的超时参数调整为更大的值,比如1000毫秒(1秒),给上游进程足够的时间输出数据:
    ret = poll(&fds, 1, 1000);
    
  • 循环轮询检测:如果需要更灵活的等待逻辑,可以循环调用poll(),直到检测到数据或达到总超时时间:
    int total_wait_ms = 5000; // 总等待5秒
    int interval_ms = 100;    // 每次检测间隔100毫秒
    int ret = 0;
    struct pollfd fds = {.fd = 0, .events = POLLIN};
    
    while (total_wait_ms > 0 && ret == 0) {
        ret = poll(&fds, 1, interval_ms);
        total_wait_ms -= interval_ms;
    }
    
  • 增加错误处理:不要忽略poll()返回-1的情况(系统调用失败),补充错误判断:
    if (ret == -1) {
        perror("poll failed");
        return;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:05:13