进程间通信

进程间通信

进程间通信介绍

进程间通信目的

a. 数据传输:一个进程需要将它的数据发送给另外一个进程。
b. 资源共享: ## 标题多个进程之间共享同样的资源。
c. 通知时间: 一个进程需要向另外一个或一组进程发送通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

进程间通信发展

  • 管道
  • System V 进程间通信
  • POSIX进程间通信

管道

什么是管道

  • 管道是Unix中最古老的进程间通信形式。
  • 我们把从一个进程连接到另一个进程的一个数据流称为管道。在这里插入代码片
    在这里插入图片描述

匿名管道pipe

功能:创建一无名管道
原型:int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码

在这里插入代码片#include <iostream>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cassert>
#include <sys/types.h>
#include <sys/wait.h>

#define NUM 1024
using namespace std;

int main()
{
    // 第一步:创建管道文件,打开读写端
    int fds[2];
    int n = pipe(fds);
    assert(n == 0);
    // 第二步:创建子进程
    pid_t id = fork();
    assert(id >= 0);
    if(id == 0)
    {
        // 子进程进行写入
        close(fds[0]);
        //子进程通信代码
        const char* s = "我是子进程,我正在给你发信息";
        int cnt = 0;
        while(true)
        {
            cnt++;
            char buffer[NUM];
            snprintf(buffer,sizeof buffer,"child->parent say: %s[%d][%d]",s,cnt,getpid());
            write(fds[1],buffer, strlen(buffer));
            //sleep(10000);//细节,每隔一秒休息写一次
            break;
        }
        close(fds[1]);
        exit(0);
    }

    // 父进程进行读
    close(fds[1]);
    // 父进程通信
    while(true)
    {
        //cout << "AAAAAAAAAAAAAAAAAAAAAAAAAA" << endl;
        char buffer[NUM];
        ssize_t s = read(fds[0],buffer,sizeof(buffer) - 1);
        //cout << "BBBBBBBBBBBBBBBBBBBBBBBBBB" << endl;
        if(s > 0)
        {
            buffer[s] = 0;
            cout << "Get Message# " << buffer << " | mypid: " << getpid() << endl;
        }
        else if(s == 0)
        {
            cout << "read: " << buffer << endl;
            break;
        }
        //cout << "Get Message# " << buffer << " | mypid: " << getpid() << endl;
        //sleep(5);

    }
    n = waitpid(id, nullptr, 0);
    assert(n == id);
    close(fds[0]);



    //fds[0]: read
    //fds[1]: write
    // cout << "fds[0]:" << fds[0] << endl;
    // cout << "fds[1]:" << fds[1] << endl;
    //std::cout << "Hello C++" << std::endl;
    return 0;
}

命名管道

  1. 管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
  2. 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。
  3. 命名管道是一种特殊类型的文件

命名管道:是一个文件,读写端进程共同打开同一个文件,以不同的方式打开,实现通信需求。

管道的读写规则

a. 读慢,写快
管道写满时,write 调用阻塞,等待对方进程进行读取
b. 读快,写慢
没数据可读时,read调用阻塞,即读进程暂停执行,一直等到写端有数据写入时。
c. 写端关闭,则read端,返回0
d.读端关闭,则write端操作会产生信号SIGPIPE(可以用kill -l linux命令查看SIGPIPE是什么意思),导致操作系统发送信号,write端进程退出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘家的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值