匿名管道和命名管道

管道是进程通信的一种方式。(进程通信需要让不同进程看到同一份资源

管道分为匿名管道和命名管道两种。

管道只允许单向通信。

一.匿名管道

#include<iostream>
#include <unistd.h>
#include<cassert>
#include<cstring>
#include<errno.h>
#include<string>
#include <sys/types.h>
#include <sys/wait.h>

//父写子读
int main()
{
//父进程创建管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    assert(n == 0);
    (void*)n;
    std::cout << "pipefd[0]" << pipefd[0] << "pipefd[1]" << pipefd[1] << std::endl;

    //创建子进程
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork false\n");
        return 1;
    }
    if(id == 0) //子进程读
    {
        close(pipefd[1]); //关闭写
        //to do
        while(true)
        {
            char ret[100];
            ssize_t n = read(pipefd[0], ret, sizeof(ret) - 1);
            if(n > 0)
            {
                ret[n] = '\0';
                std::cout << "child read:" << ret << std::endl;
            }
            else if(n == 0)//代表read读不到内容时返回0
            {
                break;
            }
        }
        //关闭所有fd
        close(pipefd[0]);
        exit(0);
    }

    //父进程
    close(pipefd[0]); //关闭读
    //to do
    std::string s = "i am father";
    write(pipefd[1], s.c_str(), strlen(s.c_str()));
    sleep(5);
    //关闭所有fd
    close(pipefd[1]);
    //回收子进程
    pid_t rid = waitpid(id, nullptr, 0);
    if(rid == id)
    {
        std::cout << "wait success" << std::endl;
    }


    return 0;
}

 

 

二.命名管道

1.命令行创建命名管道

【】$ mkfifo filename

2.代码创建


 

A写B读 

#include<iostream>
#include<cassert>
#include<cstring>
#include<errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//A写  B读
int main()
{
//创建命名管道
    int n = mkfifo("fifo", 0666);
    if(n < 0)
    {
        perror("mkfifo false\n");
        return 1;
    }
    int fd = open("fifo", O_WRONLY);
    if(fd < 0)
    {
        perror("open fail\n");
        return 1;
    }
    //写入内容
    std::string ms = "i am process A";
    write(fd, ms.c_str(), ms.size());

    close(fd);

    return 0;
}

 

#include<iostream>
#include<cassert>
#include<cstring>
#include<errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int fd = open("fifo", O_RDONLY);
    if(fd < 0)
    {
        perror("open fail\n");
        return 1;
    }
//读取内容
    char ret[1024];
    while(true)
    {
        ssize_t n = read(fd, ret, sizeof(ret) - 1);
        if(n > 0)
        {
            ret[n] = '\0';
            std::cout << "B read :" << ret << std::endl;
        }
        else if(n == 0)
        {
            break;
        }
    }
    close(fd);
    return 0;
}

三.管道4种情况,5种特性

a.5种特性:

1.匿名管道,只允许具有血缘关系的进程之间进行通信,常用于父子;

命名管道,任意进程。

2.管道默认给读写端提供同步机制

3.面向字节流的

4.管道的生命周期是随进程的

5.管道是单向通信的(一个进程读,另一进程写)

 b.4种情况

1.如果管道没有数据了,读端必须等待,直到有数据为止(写端写数据)。

2.如果管道被写满了,写端必须等待,直到有空间为止(读端读走数据)

3.写端关闭,读端一直读取,读端会读到read返回值为0,表示文件结尾

4.读端关闭,写端一直写,os会直接杀掉写端进程,通过向目标进程发送SIGPIPE(13)信号,终止目标进程。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
匿名管道命名管道都是用于进程间通信的方式,但它们之间有一些区别。 匿名管道匿名管道是一种单向通信方式,只能用于父子进程或者兄弟进程之间的通信。在创建匿名管道时,操作系统会自动为其分配一个文件描述符,通过该文件描述符,进程可以进行读写操作。 匿名管道的创建方式如下: ```C int pfd[2]; pipe(pfd); // 创建匿名管道 ``` 其中,pfd[0]是管道的读端,pfd[1]是管道的写端。 匿名管道的使用方式如下: ```C char buf[1024]; pid_t pid; int pfd[2]; pipe(pfd); pid = fork(); if (pid == 0) { // 子进程 close(pfd[1]); // 关闭写端 read(pfd[0], buf, sizeof(buf)); // 读取数据 printf("child process read from pipe: %s\n", buf); close(pfd[0]); // 关闭读端 } else if (pid > 0) { // 父进程 close(pfd[0]); // 关闭读端 write(pfd[1], "hello world", strlen("hello world")); // 写入数据 close(pfd[1]); // 关闭写端 } else { perror("fork"); exit(1); } ``` 命名管道命名管道也是一种单向通信方式,但可以用于任意进程之间的通信。在创建命名管道时,需要指定一个路径名,并且需要手动创建该文件。操作系统会为其分配一个文件描述符,通过该文件描述符,进程可以进行读写操作。 命名管道的创建方式如下: ```C int fd; mkfifo("/tmp/myfifo", 0666); // 创建命名管道 fd = open("/tmp/myfifo", O_RDONLY); // 打开命名管道 ``` 其中,"/tmp/myfifo"是文件路径名,0666是文件权限。 命名管道的使用方式如下: ```C char buf[1024]; int fd; fd = open("/tmp/myfifo", O_RDONLY); read(fd, buf, sizeof(buf)); // 读取数据 printf("read from fifo: %s\n", buf); close(fd); ``` 需要注意的是,命名管道的写入操作可以在任意进程中进行,只要有权限打开该文件即可。如果多个进程同时写入数据到同一个命名管道,可能会导致数据混乱。因此,使用命名管道时需要特别注意数据的同步问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值