在Linux中,管道(pipe)是一种用于进程间通信(IPC)的机制,它允许数据在两个进程之间单向传输。管道有两种类型:匿名管道和命名管道(FIFO)。
匿名管道
匿名管道通常用于具有父子关系的进程之间的通信。它由 pipe()
系统调用创建。匿名管道只存在于创建它的进程及其子进程之间。匿名管道创建后,生成一对文件描述符,一个用于读取,另一个用于写入。
以下是使用匿名管道进行父子进程间通信的示例:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int pipefd[2];
pid_t cpid;
char buf;
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* 子进程 */
close(pipefd[1]); /* 关闭写端 */
while (read(pipefd[0], &buf, 1) > 0) {
write(STDOUT_FILENO, &buf, 1);
}
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* 父进程 */
close(pipefd[0]); /* 关闭读端 */
const char *msg = "Hello from parent";
write(pipefd[1], msg, strlen(msg));
close(pipefd[1]); /* 关闭写端 */
wait(NULL); /* 等待子进程 */
exit(EXIT_SUCCESS);
}
}
命名管道(FIFO)
命名管道可以在无亲缘关系的进程之间进行通信。它在文件系统中存在,使用 mkfifo
命令或 mkfifo()
系统调用创建。命名管道通过路径名进行访问。
以下是使用命名管道进行进程间通信的示例:
-
创建命名管道(通常在 shell 中执行):
mkfifo /tmp/myfifo
-
写入进程(writer.c):
#include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { const char *fifo_path = "/tmp/myfifo"; const char *msg = "Hello from writer"; int fd = open(fifo_path, O_WRONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } write(fd, msg, strlen(msg)); close(fd); return 0; }
-
读取进程(reader.c):
#include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { const char *fifo_path = "/tmp/myfifo"; char buf[128]; int fd = open(fifo_path, O_RDONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } ssize_t num_bytes = read(fd, buf, sizeof(buf) - 1); if (num_bytes == -1) { perror("read"); exit(EXIT_FAILURE); } buf[num_bytes] = '\0'; // Null-terminate the string printf("Read from FIFO: %s\n", buf); close(fd); return 0; }
代码编译和运行
-
编译代码:
gcc writer.c -o writer gcc reader.c -o reader
-
运行写入进程:
./writer
-
在另一个终端窗口运行读取进程:
./reader
总结
- 匿名管道:适用于父子进程间的通信,使用
pipe()
系统调用创建。 - 命名管道(FIFO):适用于无亲缘关系的进程间通信,使用
mkfifo
命令或mkfifo()
系统调用创建。
通过管道,进程可以高效地进行数据传输,实现进程间的协同工作。
标签:--,pipefd,管道,fd,内核,进程,include,buf From: https://www.cnblogs.com/whcjob/p/18205737