pipe

创建一个无名管道,并且打开读写端;

头文件:
    #include <unistd.h>
原型:
    int pipe(int pipefd[2]);
参数:
    int pipefd[2]:存储两个打开的文件描述符,需要传入一个int类型的数组,且容量为2;
        pipefd[0]:读端;
        pipefd[1]:写端;
返回值:
    成功,返回0;
    失败,返回-1,更新errno;
例程:
    int pfd[2];
    if(pipe(pfd) < 0)
    {
        perror("pipe");
        return -1;
    }

关闭管道

close(pfd[0]);        //关闭读端
close(pfd[1]);        //关闭写端

往无名管道 write 写数据

close(pfd[0]);        //关闭读端
char buf[N] = "";
int ret  = write(pfd[1], buf, strlen(buf));
if(ret < 0)
{
    perror("write");
    break;
}
close(pfd[1]);         //关闭写端

从无名管道 read 读数据

close(pfd1[1]);        //关闭写端
char buf[N] = "";
int ret = read(pfd1[0], buf, sizeof(buf));
if(ret < 0)
{
    perror("read");
    break;
}
else if(0 == ret)
{
    printf("对方关闭\n");
    break;
}
printf("%s\n", buf);
close(pfd1[0]);        //关闭读端

应用例程

使用无名管道实现父子进程对话

  1. 父进程发送一句话,子进程接收打印;
  2. 子进程发送一句话,父进程接收打印。
  3. 重复1)2)两步骤
  4. 当父进程或子进程收到quit QUIT Quit,结束父子进程。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    int pfd[2];
    if(pipe(pfd) < 0)
    {
        perror("pipe");
        return -1;
    }
    int pfd1[2];
    if(pipe(pfd1)<0)
    {
        perror("pipe");
        return-1;
    }
    pid_t pid = fork();
    if(pid > 0)
    {
        //父进程
        close(pfd[0]);        //关闭读端
        close(pfd1[1]);        //关闭写端
        //向管道中写数据
        char buf[100] = "";
        while(1)
        {
            bzero(buf, sizeof(buf));
            //从终端获取数据
            printf("父亲请输入>>>");
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = 0;     //删除最后的'\n'字符
            int ret  = write(pfd[1], buf, sizeof(buf));
            if(ret < 0)
            {
                perror("write");
                break;
            }
            if(strncasecmp(buf, "quit", 4) == 0)
            {
                break;
            }
            //读取pfd1管道中的数据
            bzero(buf, sizeof(buf));
            ret = read(pfd1[0], buf, sizeof(buf));
            if(ret < 0)
            {
                perror("read");
                break;
            }
            else if(0 == ret)
            {
                printf("对方关闭\n");
                break;
            }
            printf("儿子说:%s\n", buf);
            if(strncasecmp(buf, "quit", 4) == 0)
            {
                break;
            }
        }
        close(pfd[1]);         //关闭写端
        close(pfd1[0]);        //关闭读端
        wait(NULL);
    }
    else if(0 == pid)
    {
        //子进程
        close(pfd[1]);        //关闭写端
        close(pfd1[0]);        //关闭读端
        //从管道中读取数据
        char buf[100] = "";
        while(1)
        {
            bzero(buf, sizeof(buf));
            int ret = read(pfd[0], buf, sizeof(buf));
            if(ret < 0)
            {
                perror("read");
                break;
            }
            else if(0 == ret)
            {
                break;
            }
            printf("父亲说:%s\n", buf);
            if(strncasecmp(buf, "quit", 4) == 0)
            {
                break;
            }
            //发送数据到pfd1[1];
            bzero(buf, sizeof(buf));
            //从终端获取数据
            printf("儿子请输入>>>");
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = 0;     //删除最后的'\n'字符
            ret  = write(pfd1[1], buf, sizeof(buf));
            if(ret < 0)
            {
                perror("write");
                break;
            }
            if(strncasecmp(buf, "quit", 4) == 0)
            {
                break;
            }
        }
        close(pfd[0]);         //关闭读端
        close(pfd1[1]);        //关闭写端
    }
    else
    {
        perror("fork");
        return -1;
    }
    return 0;
}

结果

Last modification:2021 年 04 月 08 日 03 : 09 : 54