Linux进程常见通信方式

news2024/11/13 19:32:55

文章目录

  • 1、管道
    • <1>匿名管道
    • <2> 命名管道
  • 2、共享内存
  • 3、信号量

为什么要进程要进行通信呢?

进程间可能存在特定的协同工作的场景,这个时候就需要一个进程把自己的数据交付给另一个进程,让其进行处理。

进程通信的本质

因为进程具有独立性,那么两个进程要互相通信,必须得先看到同一份资源(一段内存,内存可以以文件方式提供、也可能以队列的方式提供、也可能提供的就是原始的内存块)。进程通信的本质就是,由操作系统参与提供一份所有通信进程都能看到的资源

通信的方式

1、管道

什么是管道

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

<1>匿名管道

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

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从文件描述符中读取数据
参数:fd:文件描述符,buf:目标缓存区, count:期望读取的数据字节大小
返回值:如果成功,则返回读取的字节数(0表示文件结束),读取出错返回-1

ssize_t write(int fd, const void *buf, size_t count);
功能:向文件描述符中写入数据
参数:fd:文件描述符,buf:目标缓存区, count要写入的数据字节大小
返回值:如果成功,则返回写入的字节数(0表示什么都没有写入)。如果出错,返回-1

读写规则

1、如果所有管道写端对应的文件描述符被关闭,则read返回0
2、如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出
3、当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
4、当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

代码
在这里插入图片描述

运行结果:

在这里插入图片描述

通过上面的3, 4我们可以注意到为啥不是3,5或3,6呢?其实文件描述符的本质就是个数组,因此是有顺序的。

Linux下管道大小

我们可以把上面代码中的29行放开,每次只写一个字符进去,50行读的时间延迟执行就会发现,管道是有大小的,大小为64KB。如下图运行结果:
在这里插入图片描述
上面读写规则中的第三四条也就是因为这个原因。

站在文件描述符角度理解管道

在这里插入图片描述

站在内核角度理解管道

看待管道,就如同看待文件一样!管道的使用和文件一致,迎合了“Linux一切皆文件思想”。

匿名管道特点

1、只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。
2、管道提供流式服务(面向字节流的)
3、一般而言,进程退出,管道释放,所以管道的生命周期随进程
4、一般而言,内核会对管道操作进行同步与互斥(自带同步互斥)
5、管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道

通信中的四种情况
1.读端不读或读的慢,写端(写满后)要等待读端
2.读端关闭,写端收到SIGPIPE信号直接终止
3.写端不写或写的慢,读端要等写端
4.写端关闭,读端要读完pipe内部的数据然后在读,会读到0表示读到文件结尾。

<2> 命名管道

为了解决匿名管道只能父子通信,引入了命名管道。

命名管道创建

命令行创建

mkfifo filename
在这里插入图片描述
通过程序创建
相关函数:

int mkfifo(const char *filename,mode_t mode)
功能:创建一个特殊文件
参数:filename: 文件名,mode: 权限模式
返回值:成功返回0,失败返回-1

用命名管道实现server&client通信

server
在这里插入图片描述

client

在这里插入图片描述

运行结果:
在这里插入图片描述

命名管道和匿名管道的区别

1、匿名管道由pipe函数创建并打开。
2、命名管道由mkfifo函数创建,打开用open
3、FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

2、共享内存

原理

1、通过调用库函数shmget,在内存中创建一块内存空间。
2、通过调用库函数shmat,让进程 “挂接” 到这块共享内存上。
如图:
在这里插入图片描述
相关函数

功能:用来创建共享内存
原型 int shmget(key_t key, size_t size, int shmflg);
参数:
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

shmflg中的
IPC_CREAT:to create a new segment,单独使用或flg为0,创建共享,内存若已存在则返回共享内存
IPC_EXCL : 单独使用没有价值
IPC_CREAT | IPC_EXCL 失败返回-1,若我成功则得到一定是最新共享内存

功能:生成key秘钥
原型:key_t ftok(const char *pathname, int proj_id);
参数:
pathname:路径名, proj_id是子序号,它是一个8bit的整数。即范围是0~255。
返回值:如果成功,将返回生成的key_t值。失败时返回-1

功能:将共享内存段连接到进程地址空间 (attach)
原型 void *shmat(int shmid, const void *shmaddr, int shmflg);
参数 shmid: 共享内存标识 shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

功能:将共享内存段与当前进程脱离 (detach)
原型 int shmdt(const void *shmaddr);
参数 shmaddr:由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

功能:用于控制共享内存
原型 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

在这里插入图片描述

用享内存实现server&client通信

server端
在这里插入图片描述

client端
在这里插入图片描述
运行结果:
在这里插入图片描述

3、信号量

什么是信号量

管道,共享内存、消息队列都是以传输数据为目的的。
信号量不是以传输数据为目的的,他是通共享资源的方式来达到多个线程的同步和互斥的目的的。

学习信号量我们要知道的几个概念

1、信号量的本质:是一个计数器,类似 int count;衡量临界资源中资源数目的。
2、什么是临界资源:凡是能够被多个执行流同时能够访问的资源就是临界资源,如管道,共享
内存,消息队列等都是临界资源。
3、什么是临界区:进程代码有很多,其中用来访问临界资源的代码,就叫做临界区。
4、什么是原子性:一件事要么不做,要做就做完,没有中间态,就叫做原子性。
5、什么是互斥:在任意时刻只允许一个执行流进入临界资源,执行它自己的临界区。
6、什么是同步:让访问临界资源的过程在安全的前提下,有一定顺序性。

信号量的代码我们在后面的生产消费者模型中讲解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12902.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OAuth2.o的授权码模式为什么要用code获取token?

授权码模式&#xff08;Authorization Code&#xff09;是 OAuth 功能最齐全、流程最严谨&#xff0c;也是最常用的授权模式。 假设我们要用微信账号登录网易云音乐&#xff0c;需要以下五步&#xff1a; 访问网易云音乐客户端&#xff0c;客户端跳转到微信授权页面&#xff…

神经网络初体验

文章目录前言相关概念BP神经网络具体过程正馈反向传播总结前言 本博客仅做学习笔记&#xff0c;如有侵权&#xff0c;联系后即刻更改 科普&#xff1a; 参考博客:《老饼讲解神经网络》 相关概念 神经网络 模仿人的神经网络构建出来的数学模型 是人工智能的一个主力算法 神经…

STM32 BSRR BRR ODR 寄存器解析(F4系列已经去掉BRR寄存器了)

STM32 BSRR BRR ODR 寄存器解析&#xff08;F4系列已经去掉BRR寄存器了&#xff09;一、用法二、解释三、BSRR、BRR、 ODR 之间的关系G0x0系列GPIO寄存器 F4系列GPIO寄存器&#xff08;没有BRR寄存器了&#xff09; 一、用法 经常会看到类似如下的宏定义语句&#xff0c;用…

tomcat出现中文乱码原因和解决办法(简单快捷易懂)

一、遇到问题 双击打开tomcat中的bin目录下的startup.bat会出现乱码问题 或者cmd里面打开也是乱码的问题 二、出现这个问题的原因 这是因为windows下的默认编码是GBK编码&#xff0c;tomcat默认编码是UTF-8编码 解决思路&#xff1a;那就把tomacat的默认编码改为和windows下…

HTML5-框架-计算机应用2115-2022年11月17日13:57:13

目录 HTML栅格化布局框架 2、demo演示 栅格化理论&#xff1a; 栅格化系统&#xff1a; 网页栅格化&#xff1a; 重点掌握内容&#xff1a; 练习目标: HTML栅格化布局框架 1、将整个HTML浏览器的宽度设为单位1&#xff0c;那么为了操作栅格化方便&#xff0c;我们拆分…

最简单的java工具(JDK+IDEA)安装教程

一、安装包的准备 安装 java 开发者工具的话&#xff0c;分为 JDK IDEA 的安装&#xff0c;网上有很多版本是需要手动配置环境变量的&#xff0c;对大多数新手朋友来说&#xff0c;并不是很友好,下面我分享一种最快捷的安装方法&#xff1a; JDK 官网下载地址&#xff1a;htt…

服务器——SSL/TLS协议信息泄露漏洞(CVE-2016-2183)修复办法

前言&#xff1a;近期某台Windows Server服务器的远程连接端口(3389)被扫出了SSL/TLS协议信息泄露漏洞(CVE-2016-2183),尝试了网上很多复制来复制去的"解决方法",直接导致堡垒机连不上服务器,每次连不上服务器又得去找服务器提供方,真的非常麻烦,在此不得不吐槽一下某…

anaconda+pytorch安装+pycharm环境配置

首先安装anaconda 网址&#xff1a;Anaconda Installers and Packages 我根据需要选择最新的windows-x86版&#xff0c;其他根据需要选择windows和linux,mac系统版本 安装正常安装&#xff0c;安装路径要记住&#xff0c;没有没配置环境变量要用到&#xff0c;安装后运行如果…

字节三面“凉凉”了,面试题与细节回顾,Java程序员的我太难了

面试字节&#xff0c;目前还记得一些细节&#xff0c;暂时先写一篇面经回顾一下吧~文末会有面试资料分享 字节跳动一面 HashTable、Hashmap. Hashtree的区别线程池相关,线程池的流程&#xff0c;参数线程池alivetime存活时间怎么控制cas讲一下redis讲-下,项目里怎么用redis的分…

Linux实用操作-----软件的安装

教程推荐&#xff1a;Linux零基础快速入门到精通 1、Linux系统的应用商店 操作系统安装软件有许多种方式&#xff0c;一般分为&#xff1a; •下载安装包自行安装 •如win系统使用exe文件、msi文件等 •如mac系统使用dmg文件、pkg文件等 •系统的应用商店内安装 •如win…

图算法介绍

为什么要用图算法 图算法有助于我们理解关联数据。理解网络及其内部联系可以为洞察和创新提供不可思议的潜力。 图算法特别适用于理解结构和揭示高度关联的数据集中模式。目前&#xff0c;大数据汇集、混合和动态更新的需求非常强烈&#xff0c;图算法有助于体现数据的关联性…

树结构的实际应用

堆排序 堆排序的介绍 堆排序利用堆这中数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它是不稳定排序堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其它左右孩子节点的值,称为大顶堆,注意:没有要求节点的左孩子和右…

苹果电脑的文件怎么复制到移动硬盘,macbook文件怎么拷贝到移动硬盘

如果我们使用的是Mac电脑&#xff0c;刚好需要将一些文件从Mac复制到NTFS外置硬盘&#xff0c;那么&#xff0c;苹果电脑的文件怎么复制到移动硬盘&#xff1f; 一、如何将文件从Mac电脑上复制到NTFS外置硬盘&#xff1f; 我可以在Mac上正常使用NTFS外置硬盘吗&#xff1f;很多…

Linux【搭建环境与基本指令】

Linux【搭建环境与基本指令】&#x1f34e;一.Linux搭建环境&#x1f352;1.1什么是Linux&#x1f349;1.1.1Linux介绍&#x1f349;1.1.2CentOS 和 RedHat 的关系&#x1f349;1.1.3在Java中应用到Linux的方面&#x1f352;1.2XShell的安装与使用&#x1f349;1.2.1XShell的安…

定时器的使用和线程安全

在linux下如果对定时要求不太精确的话&#xff0c;使用alarm()和signal()就行了&#xff1b; 但是如果想要实现精度较高的定时功能的话&#xff0c;就要使用setitimer函数。 核心api&#xff1a; int setitimer(int which, const struct itimerval *value, struct itimerval *…

【李宏毅】机器学习-RNN

RNN(Recurrent Neural Network) 为什么需要RNN呢&#xff1f; 举例来说&#xff0c;有一个任务需要识别每个单词代表的含义。在下面的句子中&#xff0c;taipei分别表示目的地和出发地&#xff0c;我们希望神经网络能够在不同的句子中&#xff0c;识别出不同的语义&#xff0c;…

3、排序(order by)与分页(limit)多表查询 -mysql

3、排序与分页&多表查询 -mysql排序与分页一、排序 Order By二、分页 Limit多表查询一、一个案例引发的多表连接2、笛卡尔积&#xff08;或交叉连接&#xff09;的理解二、多表查询分类讲解1、等值连接 vs 非等值连接2、自连接 vs 非自连接3、内连接 vs 外连接三、SQL99语法…

pytorch深度学习实战lesson18

第十八课 卷积层 卷积是深度学习最重要的概念之一&#xff0c;下面来学习和回顾一下卷积的基本概念。 目录 理论部分 从全连接层到卷积层 卷积层 实践部分 理论部分 从全连接层到卷积层 还是从一个例子开始&#xff1a;假设我要对猫和狗进行分类。 假设我用一千二百万像…

3年经验,光靠自动化测试基础,你可能连17k的测试岗都找不到,认清现实.....

相信对于每一个求职者来说都有被面试的经历吧&#xff0c;曾经作为一位测试小白的我&#xff0c;每一次面试过后都会各种吐槽面试官的不是&#xff0c;吐槽HR人事的不足&#xff0c;以及自己的有点没有发挥出来&#xff0c;今天我终于体会了一次面试官的心情.... 起因&#xf…

【夯实Kafka知识体系及基本功】分析一下(Broker)服务的可靠性机制分析「原理篇」

副本机制 分布式系统中&#xff0c;为了提高可靠性&#xff0c;最常用、最有效的策略是“副本机制”&#xff0c;Kafka也不例外。 Kafka 为每个 Partition 维护了一个 AR&#xff08;Assigned Replicas&#xff09;列表&#xff0c;由 ISR&#xff08;In-Sync Replicas&#x…