Linux无名管道

无名管道的特点

无名管道属于单向通讯

无名管道只能用于父子进程通讯

无名管道发送端叫做写端,接收端叫做读端

无名管道将读端与写端抽象成两个文件进行操作,在无名管道创建成功之后,则会将读端与写端的文件描述符存入数组

创建无名管道

pipe()

c 复制代码
#include <unistd.h>
int pipe(int pipefd[2]);

功能

管道创建之后,内核会将文件描述符存储到数组

函数参数

c 复制代码
pipefd:用于存储无名管道读端与写端的文件描述符的数组
pipefd[0]:读端文件描述符
pipefd[1]:写端文件描述符

函数返回值

c 复制代码
成功:0
失败:-1,设置 errno

示例代码

创建一个子进程,负责循环从管道中读取数据,父进程从键盘读取数据后,写入到管道中,输入 "quit" 字符

串时退出

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
  
int main() {
      int pipefd[2];
      pid_t pid;
      char buf[1024];
  
      if (pipe(pipefd) == -1) {
          perror("pipe");
          exit(EXIT_FAILURE);
      }
  
      pid = fork();
      if (pid == -1) {
          perror("fork");
          exit(EXIT_FAILURE);
      }
  
      if (pid == 0) {
          close(pipefd[1]);
          while (1) {
              memset(buf,0,strlen(buf));
              ssize_t n = read(pipefd[0], buf, sizeof(buf));
              if (n <= 0||(strncmp(buf,"quit",4)==0)) {
                  printf("fork 退出!\n");
                  break;
              }
              putchar('\n');
              printf("子进程接收到: %s\n", buf);
          }
          close(pipefd[0]);
          exit(EXIT_SUCCESS);
      } else {
          close(pipefd[0]);
          while (1) {
              memset(buf,0,strlen(buf));
              printf("请输入要发送的数据(输入 'quit' 退出):");
              fgets(buf, sizeof(buf), stdin);
              buf[strlen(buf)-1]='\0';
              write(pipefd[1], buf, strlen(buf));
              if (strncmp(buf, "quit", 4) == 0) {
                  close(pipefd[1]);
                  break;
              }
          }
          wait(NULL);
      }
    return 0;
}