首页 > 系统相关 >进程间通信方式--匿名管道通信

进程间通信方式--匿名管道通信

时间:2023-04-05 09:44:36浏览次数:34  
标签:pipe -- pipefd 管道 间通信 int 匿名 进程 include

管道的特点

  • 管道其实是一个在内核内存中维护的缓冲器,这个缓冲器的存储能力时有限的,不同的操作系统大小不一定相同。
  • 管道拥有文件的特质:读操作、写操作,匿名管道没有文件实体,有名管道由文件实体,但不存储数据。可以按照操作文件的方式对管道进行操作。
  • 一个管道是一个字节流,试用管道时不存在消息或消息边界的概念,从管道读取数据的进程可以读取任意大小的数据块,而不管写入进程写入管道的数据块的大小是多少。
  • 通过管道传递的数据是顺序的,从管道里读出数据的顺序和它们被写入到管道里的顺序是一致的。
  • 在管道中的数据传输的方向是单向的,一端用于写入,一端用于读取,管道是半双工的。
  • 从管道读数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便写入更多数据,在管道中无法使用lseek()函数来随机的访问数据。
  • 匿名管道只能在具有公共祖先的进程(父进程与子进程、或者两个兄弟进程、具有亲缘关系)之间使用

匿名管道

  • 管道也叫无名(匿名)管道。它是UNIX系统IPC的最古老形式。所有的UNIX系统都支持这种通信机制。
  • 统计一个目录中文件数目命令:ls | wc -l,为了执行该命令,shell创建了两个进程分别来执行 ls 和 wc。

在Linux终端下输入命令:man 2 pipe查看pipe函数的具体描述:

NAME
       pipe, pipe2 - create pipe

SYNOPSIS
        #include <unistd.h>

        int pipe(int pipefd[2]);
            功能:创建一个匿名管道,用来进程间通信
            参数:
                int pipefd[2]:这个参数是个传出参数
                pipefd[0]:对应的是管道的读端
                pipefd[1]对应的是管道的写端
            返回值:
                成功返回0
                失败返回-1
        
        注意:匿名管道只能用于具有亲缘关系的管道之间。管道默认是阻塞的如果管道中没有数据
        read阻塞,如果管道满了write阻塞。

下面是pipe函数的简单案例:

  1. 父子进程交叉收发信息
  2. 查看管道缓冲大小函数
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using std::cout;
using std::endl;


namespace jj01{

//子进程发送数据给父进程,父进程读取数据输出
//父子进程交叉收发信息
    void test(){

        //在fork之前创建管道
        int pipefd[2];
        int ret = pipe(pipefd);
        if(ret == -1)
            perror("pipe");


        //创建子进程
        pid_t pid = fork();
        char buf[1024] = {0};
        if(pid > 0){
            //父进程
            //从管道读取数据
            cout << "i am parent,pid: "<<getpid()<<endl;

            
            //不断从管道中读数据
            while(1){
                int leng = read(pipefd[0],buf,sizeof(buf));
                cout << "parent recv : "<<buf<<" pid:"<<getpid()<<endl;

                //管道中写数据
                const char *str = "hello,i am parent";
                write(pipefd[1],str,strlen(str));
                sleep(1);
            }
            
        }
        else if(pid == 0){
            //子进程
            cout << "i am child,pid: "<<getpid()<<endl;
            //不断向管道中写数据
            while(1){
                const char *str = "hello,i am child";
                write(pipefd[1],str,strlen(str));
                sleep(1);

                //从管道中读数据
                int leng = read(pipefd[0],buf,sizeof(buf));
                cout << "child recv : "<<buf<<" pid:"<<getpid()<<endl;
            }

            
        }
    }
        
}

namespace jj02{

    /*
查看管道缓冲大小命令:ulimit -a

查看管道缓冲大小函数
#include <unistd.h>

       long fpathconf(int fd, int name);
       参数:
        int fd:文件描述符
        int name:_PC_PIPE_BUF   获取管道的大小


*/

    void test(){
        int pipefd[2];
        int ret = pipe(pipefd);

        //获取管道的大小
        long psize = fpathconf(pipefd[0],_PC_PIPE_BUF);
        cout <<"管道的大小:"<< psize << endl;

    }
}


int main(){

    //jj01::test();
    jj02::test();
    return 0;
}

标签:pipe,--,pipefd,管道,间通信,int,匿名,进程,include
From: https://www.cnblogs.com/nakjima/p/17276064.html

相关文章

  • 关于传递引用会导致的问题
    复习effectivec++的时候看到:于是来验证一下,果然会出现对应问题:#include<iostream>#include<vector>#include<math.h>#include<algorithm>#include<unordered_set>#include<set>#include<unordered_map>#include<queue>usingn......
  • 【花雕学AI】4月5日,ChatGPT中国财经背景分析:昨天沪指重返3300点,这说明了什么?
        附录:一、ChatGPT是一个可以和你聊天的人工智能程序,它可以用文字回答你的问题,也可以根据你的提示写出文章、歌词、代码等内容。ChatGPT是由一个叫OpenAI的机构开发的,它使用了一种叫做GPT的技术,这种技术可以让它从互联网上学习大量的文字信息,然后根据文字之间......
  • IOS获取蓝牙状态
    IOS获取蓝牙状态监听蓝牙状态在LinkBinariesWithLibraries中添加CoreBluetooto.framework创建CBCentralManager对象为了避免每次都获取蓝牙状态都弹窗,配置一下options将CBCentralManagerOptionShowPowerAlertKey设置为falseletoptions=[CBCentralManagerOptionShowPo......
  • Systemd入门(1)
    Systemd并不是一个命令,而是一组命令,涉及到系统管理的方方面面。$systemctl--version#命令查看Systemd的版本。**systemctl是Systemd的主命令,用于管理系统**#重启系统$sudosystemctlreboot#关闭系统,切断电源$sudosystemctlpoweroff#CPU停止工作$sudosyste......
  • 多态与虚函数1
    多态虚函数定义在成员函数前面加上virtual关键字的函数,称为虚函数。重定义(重写)的要求基类与派生类中函数名要相同函数的参数列表也要相同(参数的个数、类型、顺序)函数的返回类型一致小结:基类与派生类中的同名虚函数,除了函数体可以不一样之外,其他的全部都要保持一致。(函......
  • 2023/4 做题记录 #1
    2023/4/5P5601小D与笔试https://www.luogu.com.cn/problem/P5601读题\(1\)min,码代码\(1\)min,调代码\(7\)min。注意读入时如果发现了答案不要break掉。#include<bits/stdc++.h>usingnamespacestd;intn,q;map<string,string>x;intmain(){ scanf("%d%d"......
  • 各类题目解法总结
    各类题目解法总结一、DP性质:最优子结构,可拆解并且子问题最优,父问题最优子问题重复性,一个子问题可能会影响多个不同的下一阶段的原问题(可以从数位DP中清楚地理解)无后效性,即此时的之前状态无法直接影响未来的决策1.1区间DP常见数据范围&解题方法:数据范围类......
  • ChatGPT推荐最常用的自动化测试、性能、安全测试工具!
    ChatGPT是一种当前被广泛关注的人工智能技术,它具备生成自然语言的能力,能够完成一些简单的文本生成、对话交互等任务。ChatGPT算法的出现,打破了以前自然语言处理的瓶颈,使得机器具备了更加贴合人类想法的表达能力,也让人类在处理海量自然语言数据面前得到了很大的帮助。而ChatGPT也......
  • PyQt5 - 2
    1.什么是控件一个程序界面上的独立元素,一块矩形区域具备不同的功能,比如:用户点击,接收用户输入,展示内容,存放其它控件等2.常用控件2.1按钮QPushButton,普通按钮QCommandLinkButton,超链接按钮QRadioButton,单选按钮QCheckBox,多选按钮2.2输入控件2.2.1纯键盘输入......
  • Markdown 笔记
    标题一级标题对应一个#,依次类推,支持六级标题。字体斜体:一个星号*或者_,*或者_结尾粗体:两个星号*或者_,*或者_结尾粗斜体:三个星号*或者_,*或者_结尾列表无序列表*,+,-加空格作为标记有序列表数字.加空壳作为标记,例如1.控制层级在列表前加tab。链接[链接名称](链接地址)或者<链接......