进程通信之对象-无名管道

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-10 00:06:34

无名管道(管道=队列):在系统中无不存在这样一个文件名




例子1:用pipe()函数创建一个无名管道,实现一个进程向管道中读写信息;建立no_name_pipe1.c内容如下

#include"unistd.h"
#include"sdtio.h"
#include"stdlib.h"
#include"string.h"

int main()
{
    int fd[2];
    int ret;//管道描述符
    char write_buf[]="hellolinux!";//要向管道写入的信息
    char read_buf[128]={0};//读缓存
    ret=pipe();
    if(ret<0)
    {
        printf("create a pipe failure\n");
        return -1;
    }
    printf("create pipe succcess 写端fd[1]=%d ,读端fd[0]=%d\n",fd[1],fd[0]);
    //向管道写入信息
    write(fd[1],write_buf,sizeof(write_buf));
    //start read from pipe
    read(fd[0],read_buf,128);
    printf("read_buf=%s\n",read_buf);
    //关闭管道两端
    close(fd[0]);
    close(fd[1]);
    return 0;
  }

输出结果

这时第一次读完管道内的内容,同时也将管道(队列)里的内容删除调了,若再读取第二次就会因为没有内容可读而发生读阻塞。
例子2读阻塞验证;将read_buf里的内容清空,再读一次;添加代码如下:

int main()
{
    int fd[2];
    int ret;//管道描述符
    char write_buf[]="hellolinux!";//要向管道写入的信息
    char read_buf[128]={0};//读缓存
    ret=pipe();
    if(ret<0)
    {
        printf("create a pipe failure\n");
        return -1;
    }
    printf("create pipe succcess 写端fd[1]=%d ,读端fd[0]=%d\n",fd[1],fd[0]);
    //向管道写入信息
    write(fd[1],write_buf,sizeof(write_buf));
    //start read from pipe
    read(fd[0],read_buf,128);
    printf("read_buf=%s\n",read_buf);
    
//clear read_buf and read from pipe again
memset(read_buf,0,128);
second read from pipe 
read(fd[0],read_buf,128);
printf("second            read_buf=%s\n",read_buf);//happen the obstacle of read
//关闭管道两端
    close(fd[0]);
    close(fd[1]);
    return 0;
  }

编译运行结果:

发现second read_buf没有打印出来,此时发生了读阻塞(睡眠状态)了。
例子3写阻塞验证:将以上代码修改一下,循环写入5500次;

        char read_buf[128]={0};
        char write_buf[]="hellolinux!";
        ret=pipe(fd);
        if(ret<0)
        {
        printf("create pipe failure!\n");
        return -1;
        }
        printf("create pipe success fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);

        int i=0;
        while(i<5500)
        {
        //start to write something to the pipe
        write(fd[1],write_buf,sizeof(write_buf));
        ++i;
        }
        //若是发生阻塞,no obstacle of write to the pipe不会打印
        printf("no obstacle of write to the pipe");
        close(fd[0]);
        close(fd[1]);
        return 0;
}


运行结果:

发现没打印出no obstacle of write to the pipe,此时说明发生了写阻塞。经过几次的读入次数调节,结果得知pipe的最大缓存为65545,即64byte.

例子4实现进程间通信:用pipe()函数创建一个无名管道,实现两个进程之间的通信主进程从fd[1]端写,子进程从fd[0]端读取。

#include"unistd.h"
#include"stdio.h"
#include"sys/types.h"
#include"stdlib.h"

int main()
{
        pid_t pid;
        int process_inter=0;
        int ret;
        char write_buf[]="hello linux";
        char read_buf[128]={0};
        ret = pipe();
        ir(ret<0)
        {
        printf("create a pipe failure fd[0]=%d, fd[1]=%d\n");
        return -1;
        }
        printf("create pipe success\n");
       
        pid =fork();
        if(pid ==0)//子进程里读
        {
        int i=0;
       read(fd[0],read_buf,128); 
        printf("read_buf=%s\n",read_buf);       while(process_inter==0);//process_inter=1 exit
        for(i=0;i<5;i++)
        {
        printf("this is child process i=%d\n",i);
        usleep(100);
        }
        }
        if(pid>0)//parent process code first
        {
        int i=0;
        for(i=0;i<5;i++)
        {
        printf("this is parent process          i=%d\n",i);    
        }
        sleep(5);
        write(fd[1],write_buf,sizeof(write_buf));
        process_inter=1;
        }
        close(fd[0]);
        close(fd[1]);
        return 0;



读写流程图

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!