当我的主程序在无限循环内运行时,我试图在后台读取 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
会打印内容。可能是什么问题?
您必须将第一个参数指定为比最后打开的文件描述符更高的值。从
select
, 的手册页页面
nfds 是三个集合中编号最大的文件描述符,再加 1
更改此行,
rv = select(fd, &readCheck, NULL, &errCheck, &timeout);
到
rv = select(fd+1, &readCheck, NULL, &errCheck, &timeout);
如果您没有提及这一点,那么 select 将不会检查您的描述符,因此您将无法读取文件描述符。
您的缓冲区声明为
char buffer[64];
使用
buffer[64] = '\0';
你写的越界了。
改变
buffer[64] = '\0';
到
buffer[rv] = '\0';