Linux 进程通信(无名管道)

无名管道
无名管道是半双工的,就是对于一个管道来讲,只能读,或者写。
无名管道只能在相关的,有共同祖先的进程间使用(即一般用户父子进程)。
一个fork或者execve调用创建的子进程继承了父进程的文件描述符。
打开和关闭管道
int pipe(int filedes[2]);
在你从一个管道中读出或者写入数据,这个管道必须存在。
如果成功建立了管道,则会打开两个文件描述符,并把他们的值保存在一个整数数组中。
第一个文件描述符用于读取数据,第二个文件描述符用于写入数据。
管道的两个文件描述符相当于管道的两端,一端只负责读数据,一端只负责写数据 如果出错返回
-1,同时设置errno 关闭一个文件描述符用close()函数
关闭一个管道的所有文件描述符等于关闭这个管道(不能读不能写) pipe()函数打开管道一般不会失败
读写管道
读写管道与读写普通文件方式一样,调用write与read函数即可。
几乎不会在一个进程中打开一个管道仅供进程自己使用,管道是用来交换数据的。
因为一个进程已经能够访问它要通过管道共享的数据,和自己共享数据是没有意义的。
试图对一个管道的某一端同时进行读写操作是一个严重的错误。

 

//无名管道
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int arg, char * args[])
{
    //定义文件描述符数组
    int fdarr[2] = { 0 };
    int no = 0;
    int status;
    //create the conduit  创建一个管道 并且打开两个文件描述符
    //管道中,第一个文件描述符只读,第二个文件描述符只写
    no = pipe(fdarr);
    if (no == -1)
    {
        printf("pipe() is failed ! message :%s\n", strerror(errno));
        return -1;
    }
    //创建父子进程
    pid_t child = fork();
    if (child == -1)
    {
        printf("system is game over !\n");
        return -1;
    }
    //定义缓存字符串数组
    char buf[100] = { 0 };
    if (child == 0)
    {
        /*
         管道和文件一样,文件read函数以O_RDONLY方式打开也会阻塞,但是文件数据在本地,读取非常快,感觉不到阻塞,
         但是管道以O_RDONLY方式打开,会阻塞进程,read()函数会等待管道另一端写入数据,直到另一端关闭文件描述符
         */
        //关闭子进程中的写文件描述符--对于父子进程共享文件描述符,只在单个进程中关闭,只能将文件描述符引用减一,
        //因为父子进程中,文件描述符被引用了两次,所以需要在父子进程中分别关闭,才能使文件描述符引用次数减一
        close(fdarr[1]);
        while (read(fdarr[0], buf, sizeof(buf)) > 0)
        {
            printf("%s", buf);
            //清空缓存区
            memset(buf, 0, sizeof(buf));
        }
        //关闭子进程中读文件描述符
        close(fdarr[0]);
    } else
    {
        //关闭父进程中的读描述符
        close(fdarr[0]);
        //将键盘输入数据写入到管道中
        strcpy(buf,"fly on air!\n");
        write(fdarr[1], buf, strlen(buf));
        //关闭管道写文件描述符
        close(fdarr[1]);
        //等待子进程结束
        wait(&status);
        printf("child process is close ! message :%d\n", WEXITSTATUS(status));
    }
    return 10;
}

 

posted on 2016-09-01 14:41  寒魔影  阅读(4127)  评论(0编辑  收藏  举报

导航