在Linux系统中,管道(pipe)是一种进程间通信(IPC)机制,允许一个进程的输出成为另一个进程的输入。双向管道(也称为命名管道或FIFO)则允许两个进程之间进行双向数据交换。
以下是一个简单的双向管道示例,展示了如何在Linux中使用命名管道(FIFO)进行双向通信。
mkfifo /tmp/myfifo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
int fd = open("/tmp/myfifo", O_WRONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
char message[] = "Hello from writer!";
write(fd, message, strlen(message) + 1);
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
int fd = open("/tmp/myfifo", O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
char buffer[100];
read(fd, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
close(fd);
return 0;
}
为了实现双向通信,可以使用两个命名管道,一个用于进程A到进程B的通信,另一个用于进程B到进程A的通信。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
int fd_to_b = open("/tmp/myfifo_to_b", O_WRONLY);
int fd_from_b = open("/tmp/myfifo_from_b", O_RDONLY);
if (fd_to_b == -1 || fd_from_b == -1) {
perror("open");
exit(EXIT_FAILURE);
}
char message_to_b[] = "Hello from A to B!";
write(fd_to_b, message_to_b, strlen(message_to_b) + 1);
char buffer_from_b[100];
read(fd_from_b, buffer_from_b, sizeof(buffer_from_b));
printf("A received: %s\n", buffer_from_b);
close(fd_to_b);
close(fd_from_b);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
int fd_to_a = open("/tmp/myfifo_to_a", O_WRONLY);
int fd_from_a = open("/tmp/myfifo_from_a", O_RDONLY);
if (fd_to_a == -1 || fd_from_a == -1) {
perror("open");
exit(EXIT_FAILURE);
}
char message_from_a[100];
read(fd_from_a, message_from_a, sizeof(message_from_a));
printf("B received: %s\n", message_from_a);
char message_to_a[] = "Hello from B to A!";
write(fd_to_a, message_to_a, strlen(message_to_a) + 1);
close(fd_to_a);
close(fd_from_a);
return 0;
}
原因:权限不足或路径已存在且不是FIFO。
解决方法:
mkfifo
命令创建FIFO,如果路径已存在,先删除再创建。rm /tmp/myfifo
mkfifo /tmp/myfifo
原因:管道未正确打开或进程间同步问题。
解决方法:
select
或poll
等多路复用技术处理多个管道的读写操作。#include <sys/select.h>
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd_from_b, &readfds);
select(fd_from_b + 1, &readfds, NULL, NULL, NULL);
if (FD_ISSET(fd_from_b, &readfds)) {
read(fd_from_b, buffer_from_b, sizeof(buffer_from_b));
}
通过以上方法,可以有效解决Linux双向管道控制进程中的常见问题。
领取专属 10元无门槛券
手把手带您无忧上云