Linux进程间通信——匿名管道

一、引言

(1)匿名管道可以实现本地的父子或兄弟进程间的通信。
(2)是半双工的,数据只能向一个方向流动,如果需要实现双方通信,使用两个管道。

二、pipe函数的使用

pipe函数的原型如下:
#include <unistd.h>
int pipe(int fd[2]);
管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示。
数组中的两个文件描述符以一种特殊的方式连接起来,数据基于先进先出的原则,写到fd[1]的所有数据都可以从fd[0]读回来。由于数据基于先进先出的原则,所以读取的数据和写入的数据是一致的。

下面的例子中,在父进程中创建管道,写入数据,在子进程中读入数据,通过匿名管道实现了进程间的通信
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace  std;

#define BUF_SIZE 1024

int main()
{
    int data_process=0;
    int fd[2];
    pid_t pid;

    if(pipe(fd)==0)
    {
        // 创建管道成功
        // 创建子进程
        pid = fork();
        if(pid <0)
        {
            cout << "fork failed!" << endl;
            exit(1);
        }
        else if(pid == 0)
        {
            close(fd[1]);
            char buf[BUF_SIZE];
            memset(buf,0,sizeof(buf));
            while(1)
            {
                data_process = read(fd[0],buf,BUF_SIZE);
                cout << "Read " << data_process << " bytes: "<< buf << endl;
                if(strncmp(buf,"quit",4)==0)
                    break;
            }
            close(fd[0]);
            return 0;
        }
        else
        {
            close(fd[0]);
            char buf[BUF_SIZE];
            memset(buf,0,sizeof(buf));
            while(1)
            {
                cout << " > ";
                cin.getline(buf,BUF_SIZE);
                data_process = write(fd[1],buf,strlen(buf));
                usleep(500);
                if(strncmp(buf,"quit",4)==0)
                    break;
            }
            close(fd[1]);
            return 0;
        }
    }
    return 0;
}
注意:上述代码中,在父进程和子进程中分别关闭了fd[0]和fd[1],是因为使用fork会增加描述符的引用计数。

三、管道规则
(1)当管道中数据长度为0时,读端处于阻塞状态,等待写端写入数据
(2)当写端数据长度小于管道长度时,将以原子性写入数据
对读进程来说:
(3)当写端关闭时,当所有数据被读出后,read返回0
(4)当写端未关闭,当所有数据被读出后,读端阻塞
对写进程来说:
(5)当读端关闭时,如果写端数据长度大于管道长度时,写完管道长度时,则产生信号SIGPIPE后退出
(6)当读端为关闭,如果写端数据长度大于管道长度时,写完管道长度时,写端处于阻塞状态

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值