进程间通讯-无名管道

   在上次的博客中,我给大家介绍了进程间通讯的方式-有名管道。管道分为有名管道和无名管道,那么此次我将给大家介绍一下另一种管道通讯-无名管道。

   有名管道是可以应用于任何两个进程之间数据的单向传递,而无名管道是相对于有名管道的,无名管道在使用时产生,不使用后释放,并不会在系统上留下任何痕迹。

   无名管道因其使用前没有任何的标示,所以它只能应用于父子进程之间。原因是:调用fork函数父进程产生子进程后,子进程会通过浅拷贝的方式复制父进程的文件表数组,所以父进程和子进程可以通过同一指针访问同一内存区域。

   无名管道的操作:

       创建:int pipe(int fd[2]),其中fd[0]代表的是读操作,fd[1]代表的是写操作

       打开:int pipe(int fd[2])

       读    :read(fd[0],buff,size)

       写    :write(fd[1],buff,len)

       关闭:close(fd[0])--关闭读操作

                  close(fd[1])--关闭写操作

   注意:只要是管道通信都是半双工通讯,而无名管道创建后,父进程在fork产生了子进程后,两个进程分别有一对读写,所以,要在父子进程分别关闭读写。如果在父进程中关闭读操作,那么在子进程中就应该关闭写操作,反之亦然。

   下面请看例题:A 进程负责循环接受用户输入的数据,以”end”为结束标志,B 进程负责统计用户输入的单词个数。显示到界面上。要求用无名管道的方式实现。

   代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <memeory.h>

int main()
{   
    int fd[2];//生成fd数组
    pipe(fd);//调用生成无名管道函数pipe
    
    pid_t pid=fork();//创建进程
    assert(pid!=-1);
    
    if(pid==0)//子进程读取数据
    {
        int num=0;
        close(fd[1]);
        char buff[128]={0};
        while(1)
        {
            read(fd[0],buff,127);//读数据
            num+=strlen(buff);
            
            if(strncmp(buff,"end",3)==0)//判断end结尾
            {
                break;
            }
            printf("num=%d\n",num);
             memset(buff,0,strlen(buff));//清空buff
        }
        close(fd[0]);
    }
    else//父进程写入数据
    {
        close(fd[0]);
        printf("please input:");
        while(1)
        {
            char buff1[128]={0};
            fgets(buff1,128,stdin);
            write(fd[1],buff,strlen(buff)-1);//写入数据
            
            if(strncmp(buff,"end",3)==0)
            {
                break;
            }
        }
        close(fd[1]);
    }

}

   测试文件:

   据上图测试代码所示,用户可以循环输入,且可以显示总共输入的数据个数,当输入的数据为end时,程序结束。




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值