当前位置: 首页 > news >正文

Linux系统基础-进程间通信(2)_命名管道和System V通信

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

Linux系统基础-进程间通信(2)_命名管道和System V通信

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 命名管道

命名管道的概念: 

创建一个命名管道 

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

命名管道的打开规则 

2. system V共享内存

共享内存示意图

共享内存数据结构

共享内存函数

shmget函数

shmat函数

shmdt函数

shmctl函数

命令 : 

概念补充 : 

3. system V消息队列(简单介绍)

概念 : 

特点 : 

4. system V信号量(简单介绍)

进程同步与互斥


1. 命名管道

命名管道的概念: 

管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。

如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。

命名管道是一种特殊类型的文件

创建一个命名管道 

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

$ mkfifo filename

效果如下: 

 命名管道也可以从程序里创建,相关函数有:

int mkfifo(const char *filename,mode_t mode);

 

实例代码 :

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>int main(int argc, char *argv[])
{mkfifo("p2", 0644);return 0;
}

mkfifo("p2", 0644);: 这是创建命名管道的关键行。mkfifo 函数的两个参数如下:

"p2": 这是将要创建的命名管道的名称。这个管道将会在当前工作目录下创建一个名为 p2 的文件。

0644: 这是管道的权限位,使用八进制表示。权限位控制谁可以读取和写入该管道。将权限设置为:

用户(文件所有者)可以读和写(6)

组用户可以读(4)

其他用户可以读(4)

因此,0644 权限意味着:

拥有者具有读(r)和写(w)权限。

同组用户和其他用户具有读(r)权限,但没有写(w)权限。

效果如下: 

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

1. 匿名管道由pipe函数创建并打开

2. 命名管道由mkfifo函数创建, 打开用open

3. FIFO (命名管道) 与 pipe (匿名管道) 之间唯一的区别在它们创建与代开的方式不同, 一旦这些工作完成之后, 它们具有相同的语义. 

命名管道的打开规则 

如果当前打开操作是为读而打开FIFO时

O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO

O_NONBLOCK enable:立刻返回成功

如果当前打开操作是为写而打开FIFO时

O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO

O_NONBLOCK enable:立刻返回失败,错误码为ENXIO 

2. system V共享内存

共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据

共享内存示意图

理解 :

1. 上述所有操作, 都是OS做的

2.  OS提供上面的系统调用, 供用户A, B进行调用 --- 系统调用

3. 共享内存在系统中可以同时存在多份, 供不同个数, 不同对进程同时进行通信~!

4. OS注定了要对共享内存进行管理! --- 先描述, 在组织 --- 共享内存, 不是简单的一份内存空间, 也要有描述并管理共享内存的数据结构和匹配算法!!

5.  共享内存 == 内存空间(数据) + 共享内存的属性!

共享内存数据结构

struct shmid_ds
{struct ipc_perm shm_perm;    /* operation perms */int shm_segsz;               /* size of segment (bytes) */__kernel_time_t shm_atime;   /* last attach time */__kernel_time_t shm_dtime;   /* last detach time */__kernel_time_t shm_ctime;   /* last change time */__kernel_ipc_pid_t shm_cpid; /* pid of creator */__kernel_ipc_pid_t shm_lpid; /* pid of last operator */unsigned short shm_nattch;   /* no. of current attaches */unsigned short shm_unused;   /* compatibility */void *shm_unused2;           /* ditto - used by DIPC */void *shm_unused3;           /* unused */
};

共享内存函数

shmget函数

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

shmat函数

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

补充 : 

shmaddr为NULL,核心自动选择一个地址

shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。

shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)

shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

shmdt函数

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

 shmctl函数

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

命令 : 

命令说明
IPC_STAT把shmid_ds结构中的数据设置位共享内存的当前关联值
IPC_SET在进程有足够权限的前提下, 把共享内存的当前关联值设置为shmid_ds数据结构中给出的值
IPC_RMID删除共享内存段

补充 : 

IPC_CEAT : 如果你要创建的共享内存不存在, 创建之, 如果存在, 获取共享内存并返回(总能回去一个)

IPC_EXCL : 单独使用没有意义, 只有IPC_CREAT组合才有意义

IPC_CREAT| IPC_EXCL : 如果你要创建的共享内存不存在, 创建之, 如果存在, 出错返回 (如果我成功返回了, 就意味着shm是全新的)

注意:共享内存没有进行同步与互斥! 

概念补充 : 

同步 :

同步是指多个线程或进程在执行某些操作时,需要协调执行的顺序,以保证执行结果的正确性。在共享内存或其他共享资源的上下文中,某些操作必须在特定的顺序下进行,以防止数据不一致。 

互斥 :  

互斥是确保某个特定的代码段或资源在同一时刻只能被一个线程或进程访问。通过互斥,避免多个线程同时修改共享资源,从而导致数据不一致或竞态条件。 

注意 : 共享内存不随着进程的结束而自动释放!!! (一直存在, 直到系统重启) 我们只能手动释放或者使用指令和其他系统调用, 生命周期随内核, 而文件的生命周期随进程

3. system V消息队列(简单介绍)

概念 : 

1. 消息队列是一个先进先出 (FIFO) 结构, 允许进程以消息为单位进行数据传输, 每条消息都由一个消息类型和实际数据组成.

2. 消息队列允许不同进程之间进行异步通信, 即发送和接收消息的进程不需要同时运行

特点 : 

1. 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法

2. 每个数据快都被认为是一个类型, 接收者接收的数据块可以有不同的类型值

3. IPC资源必须清除, 否则不会自动清除, 除非重启, 所以system V IPC资源的生命周期随内核

4. system V信号量(简单介绍)

信号量是一种计数器,用于表示可用资源的数量。通过信号量,进程可以控制对共享资源的访问。

信号量主要用于同步和互斥的,下面先来看看什么是同步和互斥。

进程同步与互斥

互斥: 使用信号量可以确保同一时刻只有一个进程访问共享资源,防止数据竞争。

同步: 信号量可用于控制多个进程的执行顺序。例如,一个进程可以在资源可用时被唤醒,从而继续执行。


http://www.mrgr.cn/news/56397.html

相关文章:

  • React 基础阶段学习计划
  • SSRF-利用dict协议-攻击redis
  • 技术经济学·技术经济分析指标体系与基本原则
  • hiveserver与beeline
  • 嵌入式入门学习——6Protues点亮数码管,认识位码和段码,分辨共阴还是共阳(数字时钟第一步)
  • OpenLayers:用于在 web 应用程序中创建互动地图
  • 【linux】线程 (三)
  • python虚拟环境安装
  • [LeetCode] 814. 二叉树剪枝
  • github加速 DevSidecar 1.8.8
  • 免费送源码:Java+ssm+MySQL SSM二手物品管理系统 计算机毕业设计原创定制
  • AutoSar AP CM实例说明符的使用方法总结
  • 开头的例子的理解
  • 【系统规划与管理师】历年各章节分值汇总(论文)
  • C++ 进阶:类相关特性的深入探讨
  • 伺服增量式和绝对式的本质区别?
  • 基因检测4 - 多囊肾
  • flask服务通过gunicorn启动,supervised管理服务
  • 基于Java+ssm的名著阅读网站
  • HTTP 请求中的Content-Type
  • ECHO-GL:盈利电话驱动的异质图学习股票 走势预测
  • HTB:Headless[WriteUP]
  • 数据库实时备份软件
  • 【Linux】为什么环境变量具有全局性?共享?写时拷贝优化?
  • app端文章列表查询-详细教程(上)
  • 下载MySQL-Windows