linux系统编程学习day5--IPC之管道

来源:互联网 发布:路由器怎么限制网络 编辑:程序博客网 时间:2024/06/06 13:18

管道

管道这个方式个人感觉真的是非常简单的,先简述一下管道的概念:

管道的概念就是这些,需要注意一下的是什么是伪文件,还有就是半双工这两个概念。

伪文件:

这里管道的伪文件其实就是一块内核的缓冲区,把数据都放在这片缓冲区里面然后进行读写操作,伪文件系统是一个linux里面的一个概念,有兴趣的可以查阅一下相关的资料,有很多种伪文件,都代表不懂得意义。

半双工通信方式:

这个概念的话如果有一些嵌入式基础的会好理解的多,嵌入式里面有各种通信方式,单工,半双工,全双工这些。

半双工就是指数据可以在一个信号载体的两个方向上传输,但是不能同时传输,比如我这边可以读写你那边也能读写,但是我读的时候我不能写入,我写入的时候不能读取,在某一时刻数据只能在某一个方向流动,这就是半双工,单工就是完全单向的,全双工相应的就是读写可以同时进行的,在嵌入式里面的话有几个典型的半双工模式,例如I2C通信,RS-485等。


管道更加通俗易懂得来阐述它得概念的话就是字面意思了,就把它理解成一根水管,这根水管连接到了两个木桶里面或者两个池子里面,数据就是管道里面的水,如果我想从木桶A里面的水流到木桶B那么就需要把木桶A抬高,水流利用重力自然而然地从A到B,但是B不能到A,相反亦然。

概念理解了之后就只是如何使用的问题了,使用也十分简单,就仅仅一个pipe函数而已,pipe函数具体用法可以在linux得man page查看, man 2 pipe出现如下页面


int pipe(int pipefd[2]);

函数原型可以看出返回值是int型,默认的失败返回-1的然后参数里面的 int pipefd[2]这是一个传入参数,需要我们在外部定义一个包含两个文件描述符的数组,这个数组就是我们的管道,很简单,如果我们需要调用这个管道那么就只需要在创建出来的管道里面用wirte(fd[1],...,...), 这个value就是你需要传入的值,这里1定义为写入,0定义为读取,如果你需要读取数据就只需要read(fd[0],...,...),十分的简单。

下面的 int pipe2(int pipefd[2], int flags);

多了一个flags参数,这个参数在下面也有详细的说明,这里不细说了。


需要注意一下:

1.pipe只能在有血缘关系的进程里面进行使用,且pipe的调用必须要在fork之前。

这个应该很好理解,毕竟pipe管道应该是在父进程开辟,且子进程要继承它,如果在fork之后调用的话就是父子进程同时创建管道就会有两个管道了

2.管道使用完毕后应该及时的关闭掉。

关闭的方式就是调用一次close(pipefd[x]);

3.pipe开辟的管道成为匿名管道,如果需要在非血缘关系间进行使用的话,需要使用有名管道。


贴一个pipe的示例程序代码:

#include <stdio.h>#include <unistd.h>#include <string.h>int main(void){    int fd[2];// fd[0] read fd[1] write    pid_t pid;    int ret = pipe(fd);    if(ret == -1)    {        perror("pipe error");        return 0;     }    pid = fork();    if(pid == -1)    {        perror("fork error");        return 0;    }    if(pid == 0)    {        close(fd[1]);        char buf[1024];        ret = read(fd[0],buf,sizeof(buf));        if(ret == 0)        {            printf("----------\n\n");        }        write(STDOUT_FILENO,buf,ret);    }    else{        close(fd[0]);        write(fd[1],"这个很牛逼的数据\n",strlen("这个很牛逼的数据\n"));    }return 0;}



原创粉丝点击