Linux进程间通信 -- 管道(pipe)

管道又称匿名管道,是半双工的的进程间通信,由于没有名字所以只能在父子进程间使用,其他进程是无法获得其管道描述符的。

特点

  • 管道是半双工模式,同一时间一端只能接收或发送数据。
  • 管道是创建在内存中的,意味着进程结束后管道就不存在了。
  • 如果管道中没有数据,则读取管道数据的进程会发生读阻塞。
  • 如果管道被写满了,则会发生写阻塞。

使用场景

仅适用于父子进程间的通信,且一端只读,一端只写。因为是匿名管道所,其他进程是无法获得其管道描述符的。

创建管道

创建管道需要准备int fd[2]的数组,fd[0]是读管道,fd[1]是写管道。调用pipe()函数创建管道。

示例代码

#include <iostream>
#include <unistd.h>

using namespace std;

#define PIPE_READ  0
#define PIPE_WRITE 1

int main()
{
    pid_t fpid = 0;
    int ret = 0;
    int fd[2];

    // 创建管道,成功后fd[0]是read pipe,fd[1]是write pipe
    if (0 != pipe(fd)) {
        cout << "pipe error!" << endl;
        exit(1);
    }

    // 创建子进程
    fpid = fork();
    if (fpid > 0) {
        // 父进程,此时fpid是子进程的pid
        // 管道是半双工的,这里父进程关闭read pipe,然后给子进程发送数据
        cout << "I am father, my pid is " << getpid() << endl;
        close(fd[PIPE_READ]);

        // 为了体现读阻塞,主进程5秒后再写入数据,可以观察到5秒后子进程才输出 “Hi!”
        sleep(5);
        write(fd[PIPE_WRITE], "Hi!\n", 4);
    } else if (0 == fpid) {
        // 子进程
        // 管道是半双工的,这里子进程关闭write pipe,然后读取父进程发来的数据
        cout << "I am child, my pid is " << getpid() << endl;
        close(fd[PIPE_WRITE]);

        char buf[4] = {};
        read(fd[PIPE_READ], buf, sizeof(buf));
        cout << "Child received data: " << string(buf) << endl;
    } else {
        cout << "fork failed!" << endl;
    }

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值