Linux管道通信方式

进程间通信(IPC:Inner Proceeding Communication

进程是操作系统实现程序独占系统运行的假象的方法,每个进程都是一个独立的资源管理单元,任何一个进程的全局变量在另一个进程中都是无法看到的,因此各个进程之间是不能够直接的访问对方进程的资源的,不同的进程之间进行信息交互需要通过内核,进程A在内核中开辟一个缓冲区,并且把数据拷贝到此缓冲区中,进程B通过访问内核中的这块缓冲区,达到了进程间数据交换的目的,这就是进程间通信。


管道(pipe)

管道是一种最基本、最古老的进程间通信方式,管道又可以分为匿名管道和命名管道,两者的用途是不一样的。


 匿名管道PIPE:主要用于具有亲缘关系的进程之间的通信,匿名管道的通信是单向的,只能由一段到另外一段;匿名管道是临时性的,完成通信后将自动消失。一般采用先创建无名管道,再创建子进程,使子进程继承父进程的管道文件描述符,从而实现父子进程间的通信;在非亲缘关系管道之间,如果想利用无名管道进行通信,则需要借助另外的文件描述符传递机制。


命名管道FIFO:命名管道是一个实际存在的特殊文件,利用有命名管道可以实现同主机任意进程之间的数据交互。

使用管道需要注意的四种情况:

(1)如果所有指向写端的文件描述符都关闭了,即写端的引用计数为零,此时仍有进程从管道的读端读取数据,那么管道中能够剩下的数据都被读取之后,再次read就会返回0,这时就跟读到文件末尾一样。


代码如下

#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<sys/wait.h>
int main(){
    int _pipe[2];
    int ret=pipe(_pipe);
    if(ret==-1)
    {
        printf("creat pipe error! errno code is :%d\n",errno);
        return 1;
    }
    pid_t id=fork();
    if(id<0)
    {
        printf("fork error!");
        return 2;
    }
    else if(id==0)
    {
        close(_pipe[0]);
        int i=0;
        char* _mesg_c=NULL;
        while(i<100)
        {
            _mesg_c="i am child!";
            write(_pipe[1],_mesg_c,strlen(_mesg_c)+1);
            sleep(1);
            i++;
        }
    }
    else
        {
         close(_pipe[1]);
            char _mesg[100];
            int j=0;
            while(j<100)
            {
                memset(_mesg,'\0',sizeof(_mesg));
                read(_pipe[0],_mesg,sizeof(_mesg));
                printf("%s\n",_mesg);
                j++;
            }
            if(waitpid(id,NULL,0)<0)
            {
                return 3;
            }

        }
        return 0;
    
}

2.如果有指向管道写端的文件描述符没关闭,即引用计数大于0,而持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据被读取完之后,再次read会堵塞,直到管道中重新有了数据,此时读取数据并返回。

3.如果所有指向管道读端的文件描述符都关闭了,这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程终止。


4.如果指向管道读端的进程描述符没有关闭,而持有管道读端的进程也没有从管道中读取数据,这时有进程向管道写端写数据,那么在管道写满时再次write会阻塞,直到管道中有了空位置才写入数据并返回。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值