Linux进程间通信—管道

文章详细介绍了Linux系统中进程间通信的目的、发展历史和主要类型。重点讲解了匿名管道和命名管道的概念、工作原理、读写规则以及它们之间的区别。通过示例代码展示了如何创建和使用匿名管道进行父子进程间的通信,并提到了基于匿名管道的简易进程池实现。同时,文章还探讨了命名管道如何允许无关进程通过共享文件名进行通信。
摘要由CSDN通过智能技术生成

💘作者:泠沫
💘博客主页:泠沫的博客
💘专栏:Linux系统编程,文件认识与理解,Linux进程学习…
💘觉得博主写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!
在这里插入图片描述

🏠进程间通信

本次介绍进程通信主要是讲解如何让两个进程看到同一份资源,而不是来进行通信的。

🚀 通信目的

  • 数据传输:一个进程需要将它的数据发送给另一个进程。

  • 资源共享:多个进程之间共享同样的资源。

  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止
    时要通知父进程)。

  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另
    一个进程的所有陷入和异常,并能够及时知道它的状态改变。

总的来说,Linux进程进行通信的目的是为了协调多个进程之间的操作,共享资源和信息,提高应用程序的可靠性和强大性。

🚀 通信发展

  • 管道

  • System V进程间通信

  • POSIX进程间通信

🚀 通信分类

  • 管道
    匿名管道
    命名管道

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

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

🏠 匿名管道

🚀 匿名管道原理

匿名管道是一种在进程间进行数据传递的机制,其本质基于操作系统内核提供的缓冲区来实现。通过使用类似于文件的方式进行读写,管道可以将一个进程生成的数据传递给另一个进程,而不需要将数据写入到实际的物理文件中,这样就避免了IO操作,从而提高效率。

  1. 匿名管道的创建是由操作系统来执行的,我们可以使用一个系统调用接口pipe,让操作系统创建一个匿名管道,当成功创建管道文件后,调用该接口的进程就会拿到管道的读写端文件描述符fds[2]。
  2. 然后再调用fork接口创建子进程,子进程是以父进程的进程控制块为模板进行创建的,所以子进程的进程控制块指向的文件描述符表中的文件描述符数组和父进程一样,都保存了管道的读写端。
  3. 最后,假设我们让父进程调用close系统接口关闭写端,子进程关闭读端。仅由子进程进行写操作,父进程进行读操作。那么匿名管道就可以实现两个具有血缘关系的进程进行通信。

在这里插入图片描述
下面介绍创建匿名管道的系统调用接口pipe():
在这里插入图片描述

该系统接口的参数是一个输出型参数,需要我们自己传入一个整型数组,如果创建匿名管道成功,该数组保存的是管道的读写端文件描述符。pipefd[0]存放的是读取端的文件描述符,pipefd[1]存放的是写入端的文件描述符。

该系统接口调用成功返回0,调用失败返回-1,且错误码被设置。
接下来用代码展示如何创建匿名管道,并且实现两个父子进程进行通信。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;
int main()
{
   
    int fds[2];
    int n = pipe(fds);
    assert(n != -1);
    pid_t id = fork();
    assert(id >= 0);
    if(id == 0)
    {
   
        close(fds[0]);
        int cnt = 0;
        while(true)
        {
   
            char buffer[1024];
            snprintf(buffer, sizeof(buffer), "child -> parent say: 我是子进程[%d],pid:%d", ++cnt, getpid());
            write(fds[1], buffer, strlen(buffer));
            //sleep(100);
            sleep(1);
            if(cnt == 10)
                break;
        }   
        close(fds[1]);
        exit(0);
    }
    close(fds[1]);
    while(true)
    {
   
        //sleep(100);
        char buffer[1024];
        ssize_t num = read(fds[0], buffer, sizeof(buffer) - 1);
        if(num == -1)
        {
   
            perror("read failed");
            break;
        }
        if(num > 0)
        {
   
            buffer[num] = 0;
            cout << "Get messge: " << buffer << endl;
        }
        if(num == 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值