使用select()连续读取FIFO

问题描述 投票:0回答:2

当我的主程序在无限循环内运行时,我试图在后台读取 FIFO(使用线程)。我想使用

select()
,因为否则处理器会以 100% 的速度运行,但我发现相应的 example 无法正常工作。这是示例代码:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>

int main()
{
    mkfifo("FIFO", 0666);

    fd_set readCheck;
    fd_set errCheck;
    char buffer[64];
    struct timeval timeout;
    int rv;

    int fd = open("FIFO", O_RDONLY | O_RSYNC);

    FD_ZERO(&readCheck);
    FD_ZERO(&errCheck);

    while (1) {
        FD_SET(fd, &readCheck);
        FD_SET(fd, &errCheck);

        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        rv = select(fd, &readCheck, NULL, &errCheck, &timeout);
        if (rv < 0) {
            printf("Select failed\r\n");
            break;
        }

        if (FD_ISSET(fd, &errCheck)) {
            printf("FD error\r\n");
            continue;
        }

        if (FD_ISSET(fd, &readCheck)) {
            memset(buffer, 0, sizeof(buffer));
            rv = read(fd, buffer, sizeof(buffer));
            if (rv < 0) {
                printf("Read failed\r\n");
                break;
            }
            printf(buffer);
            buffer[64] = '\0';
        }
    }
    close(fd);

    return 0;
}

当我写入 FIFO 文件时,没有任何反应,但使用

cat FIFO
会打印内容。可能是什么问题?

c linux named-pipes fifo posix-select
2个回答
2
投票

您必须将第一个参数指定为比最后打开的文件描述符更高的值。从

select
,

的手册页页面

nfds 是三个集合中编号最大的文件描述符,再加 1

更改此行,

rv = select(fd, &readCheck, NULL, &errCheck, &timeout);

rv = select(fd+1, &readCheck, NULL, &errCheck, &timeout);

如果您没有提及这一点,那么 select 将不会检查您的描述符,因此您将无法读取文件描述符。


1
投票

您的缓冲区声明为

char buffer[64];

使用

buffer[64] = '\0';

你写的越界了。

改变

buffer[64] = '\0';

buffer[rv] = '\0';
© www.soinside.com 2019 - 2024. All rights reserved.