• Linux——匿名管道


    为什么要有进程间通信

    操作系统中,进程是独立运行的程序,多个进程之间要想互相协作完成任务,就需要进程间通信。

    什么是进程间通信?

    • 数据传输:一个进程需要将它的数据发送给另一个进程
    • 资源共享:多个进程间共享同样的资源
    • 通知事件:一个进程需要向另一个或一组进程发送消息,通知他们发送了某些事情,后者发送任务让他们执行
    • 进程控制:有些进程希望完全控制另一个进程的执行,此时进程希望能够拦截另一个进程的所有陷入和异常,并且能够及时通知它的状态改变。

    进程间通信的目的

    为了实现资源的共享,协作和同步,从而提高系统的效率和可靠性。

    进程间通信的种类

    1.管道

    • 匿名管道
    • 命名管道

    2.System V

    • 消息队列
    • 共享内存
    • 信号量

    3.POSIX V

    • 消息队列
    • 共享内存
    • 信号量
    • 互斥量
    • 条件变量
    • 读写锁

    管道的特点

    1. 管道是用来进行某种血缘关系的进程间通信的一种手段 ——一般用于父子进程
    2. 管道具有让进程间协同、提供了访问控制。(访问控制就是当一个文件里面没有数据的时候,另一方不会去读,只会阻塞等待。当文件满的时候,不能再写入了。)
    3. 管道提供了面向流式的通信服务——面向字节流
    4. 管道是基于文件的,声明周期随进程
    5. 管道是单向通信的。

    如何看到同一份资源?

    进程间通信的本质是实现资源的共享,那么最重要的一点就是如何看到同一份资源。
    先聊一聊匿名管道,匿名管道是通过父子进程后,写时拷贝后,看到的同一份资源,然后让父进程关闭读端,子进程关闭写端,这样就可以让两个进程看到同一份资源了。
    以前说过,每一个进程都有一个PCB,而每个PCB结构体中都有一个指针指向了struct file*struct,这个结构体里面就有文件描述符表,每一个文件描述表中的指针指向了每个文件。

    在这里插入图片描述

    所以父子进程通过fork后,就看到了同一份资源,如下图所示,又因为管道是单向的,关闭对应的读写端,就实现了通信。

    在这里插入图片描述

    匿名管道接口

    • pipe
      在这里插入图片描述

    成功返回0,失败返回-1,错误码被设置。pipefd是输出型参数,期望调用它,可以得到被打开的文件的fd。

    实验

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    char buffer[1024*8];
    
    int main()
    {
        //创建管道
        int pipefd[2] = {0};
        int ret = pipe(pipefd);
        assert(ret != -1);
        (void)ret;
    
        pid_t id = fork();
        assert(id != -1);
        if(id == 0)
        {
            //child
            //子进程去读,关闭写端
            close(pipefd[1]);
            // char buffer[1024*8];
            while(true)
            {
                //s == 0 是读到了文件末尾
                // s > 0 说明在有数据,还在读取
                ssize_t s = read(pipefd[0],buffer,sizeof(buffer));
                if(s > 0)
                {
                    buffer[s] = 0;
                    cout << "child get a message[" << getpid() << "] Father# " << buffer << endl;
                }
                else if(s == 0)
                {
                    cout << "write quit(father),me quit!" << endl;
                    exit(2);
                }
            }
        }
    
        //father
        //关闭读端
        close(pipefd[0]);
        string message = "我是父进程,我正在给你发信息";
        int count = 0;
        // char send_buffer[1024*8];
        while(true)
        {
            snprintf(buffer,sizeof(buffer),"%s[%d] : %d",message.c_str(),getpid(),count++);
            //向send_buffer中写入
            write(pipefd[1],buffer,strlen(buffer));
            
            sleep(1);
    
            //cout << count << endl;
            if(count == 5)
            {
                cout << "writer quit(father)" << endl;
                break;
            }
        }
    
        close(pipefd[1]);
        pid_t n = waitpid(id,nullptr,0);
        cout << "id : " << id << " "<<  "n : " << n << endl;//这里pid结果一样,说明通信成功
        assert(n > 0);
        (void)n;
    
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    实验现象: 父进程向管道里面写入,子进程读,当5s后,关闭管道。

  • 相关阅读:
    python 爬虫与协同过滤的新闻推荐系统 计算机竞赛
    【OJ每日一练】1000 — A+B Problem
    Emgu CV4图像处理之访问图像像素通道值7(C#)
    顾客点餐系统-----操作菜品JDBC代码的编写(2)
    Emlog评论区显示用户操作系统与浏览器信息教程
    讲讲URL与URI的区别
    实验 2--创建数据库和表
    UG NX二次开发(C#)-外部模式-导出dwg格式的文件
    MySQL学习笔记之单行函数
    Oracle/PLSQL: Coalesce Function
  • 原文地址:https://blog.csdn.net/m0_72165281/article/details/138037821