FIFO(First In, First Out)是一种特殊的文件类型,用于进程间的通信。它允许一个进程向另一个进程发送数据,而不需要使用临时文件或共享内存。在Linux系统中,FIFO通常通过mkfifo
命令创建,并且可以通过文件系统进行访问。
默认情况下,FIFO是阻塞的,即读取操作会一直等待直到有数据可读,写入操作会一直等待直到有空间可写。非阻塞模式则允许读取和写入操作在没有数据或空间时立即返回,而不是等待。
应用场景包括但不限于:
以下是一个简单的示例,展示如何在Linux中使用非阻塞FIFO:
mkfifo /tmp/myfifo
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int fd = open("/tmp/myfifo", O_WRONLY | O_NONBLOCK);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
for (int i = 0; i < 10; ++i) {
char buffer[20];
snprintf(buffer, sizeof(buffer), "Message %d\n", i);
write(fd, buffer, strlen(buffer));
sleep(1);
}
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int fd = open("/tmp/myfifo", O_RDONLY | O_NONBLOCK);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
char buffer[100];
while (1) {
ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
printf("Received: %s", buffer);
} else if (bytesRead == -1 && errno != EAGAIN) {
perror("read");
break;
}
sleep(1);
}
close(fd);
return 0;
}
问题:在非阻塞模式下,读取操作可能会频繁返回EAGAIN
错误,导致程序不断轮询,消耗CPU资源。
解决方法:
select
或poll
:这些系统调用可以有效地等待多个文件描述符的状态变化,避免忙等待。select
的示例#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int fd = open("/tmp/myfifo", O_RDONLY | O_NONBLOCK);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
fd_set readfds;
struct timeval timeout;
while (1) {
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeout.tv_sec = 1; // 1 second timeout
timeout.tv_usec = 0;
int ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
if (ret == -1) {
perror("select");
break;
} else if (ret > 0) {
if (FD_ISSET(fd, &readfds)) {
char buffer[100];
ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
printf("Received: %s", buffer);
}
}
}
}
close(fd);
return 0;
}
通过这种方式,可以有效减少CPU资源的浪费,同时保持程序的非阻塞特性。
领取专属 10元无门槛券
手把手带您无忧上云