Linux进程间通信方式

news2024/11/24 16:47:58

每个进程的用户空间都是独立的,不能相互访问。
所有进程的内核空间(32位系统3G-4G)都是共享的

应用场景

  • 作为缓冲区,处理速度不同的进程之间的数据传输
  • 资源共享:多个进程之间共享同样的资源,一个进程对共享数据的修改,别的进程应该立刻看到
  • 数据传输: 一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)
  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
    Linux进程间通信方式

一、管道

缺点:缓存区在内核中大小受限,只能承载无格式字节流;单向通信方式,低效,不适合频繁交换数据

生命周期随着进程创建而建立,随着进程终止而消失
遵循先进先出原则,不支持 lseek 之类的文件定位操作
需要双方通信时,需要建立起两个管道
读端不读或者读的慢,写端要等待读端;
读端关闭,写端收到SIGPIPE信号直接终止;
写端不写或者写的慢,读端要等待写端;
写端关闭,读端读完pipe内部的数据然后再读,会读到0为止,表明读到文件结尾;

1.1 匿名管道 pipe

特殊文件只存在于内存,没有存在于文件系统中
只能用于有亲缘关系的进程间
shell 命令中的竖线就是匿名管道
pipe() 和 fork() 搭配

匿名管道PIPE

1.2 有名管道 fifo

mkfifo myfifo #在文件系统中创建一个类型为 p 的设备文件

int mkfifo(const char *pathname, mode_t mode); //默认在当前的路径下创建
mkfifo("myfifo", 0666);
open("myfifo", O_RDONLY);
open(MY_FIFO, O_WRONLY);

二、消息队列

是消息的链表,存放在内核中并由消息队列标识符标识,具有足够特权的任何进程都可以往一个队列放置/读出一个消息,不需要等待消息的到达。
- 生命周期是随内核的,需要显示删除。
- 消息结构相关联的类型字段(msg_type)提供了两个特性:
(1)标识消息,使得多个进程在单个队列上复用消息。
(2)用作优先级字段,允许接收者以不同于先进先出的某个顺序读出各个消息。
优点
灵活,消息体可以自由定义,支持多种数据类型和优先级。
可靠,消息持久化且不会因发送者崩溃而丢失。
高效,支持大量数据的传输和并行处理
缺点:通信不及时; 需要访问权限;用户态与内核态之间的数据拷贝开销;有大小限制,不适合比较大数据的传输
在内核中一条消息最大长度MSGMAX 和一个队列的最大长度MSGMNB(以字节为单位)

  • 2.1 System V 消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);
int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg); //发送消息
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg); //读取消息
//cmd参数:IPC_STAT获取信息、IPC_SET设置属性、IPC_RMID删除
int msgctl(int msqid, int cmd, struct msqid_ds *buf); 
  • 2.2 POSIX 消息队列
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

mqd_t mq_open(const char *name, int oflag, ...); //打开一个已存在的消息队列,或创建一个新的消息队列
//发送消息
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio);
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);

//接收消息
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout);

//设置/获取消息队列的属性
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat);

int mq_close(mqd_t mqdes); //关闭
int mq_unlink(const char *name); //删除一个命名的消息队列。

三、共享内存最快的IPC

映射一段能被其它进程访问的内存,这段共享内存由一个进程创建,多个进程均能访问
缺点:存在进程间共享资源竞争,常与信号量配合使用
生命周期是随内核的,进程要主动删除其创建的共享内存:ipcrm -m {shmid}
共享内存块的大小都必须是系统页面大小的整数倍。系统页面大小指的是系统中单个内存页面包含的字节数。在 Linux 系统中,内存页面大小是4KB,不过您仍然应该通过调用 getpagesize 获取这个值(通过man 2 getpagesize查看 )

在这里插入图片描述
在这里插入图片描述

  • 3.1 System V 共享内存
#include <sys/ipc.h>
#include <sys/shm.h>     // shmget
#include <sys/types.h>   // key_t
// key_t ftok(const char *pathname, int proj_id);  //获取key值
// int shmget(key_t key, size_t size, int shmflg); //得到共享内存标识符,不存在时创建并返回
// void* shmat(int shmid, const void *shmaddr, int shmflg); //共享内存绑定到当前进程的地址空间中
// int shmdt(const void *shmaddr); //取消共享内存与进程地址空间之间的关联
// int shmctl(int shmid, int cmd, struct shmid_ds *buf); //cmd表示具体控制动作:IPC_STAT,IPC_SET改变状态,IPC_RMID	删除

key_t key = ftok(PATH_NAME, PROJ_ID);//获取key值
shmid = shmget(key, SIZE, IPC_CREAT | IPC_EXCL); //操作系统给用户返回的id

// ipcs命令查看有关进程间通信设施的信息
// -q:列出消息队列相关信息。
// -m:列出共享内存相关信息。
// -s:列出信号量相关信息
  • 3.2 POSIX 共享内存
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

int shm_open(const char *name, int oflag, mode_t mode);  //创建或打开一个POSIX共享内存对象
int ftruncate(int fd, off_t length); //设置大小
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); //映射到进程的地址空间
int munmap(void *addr, size_t length); //解除映射
int shm_unlink(const char *name); //删除共享内存对象

四、信号量

一个整型的计数器表示资源的数量,是为了保证进程间的同步与互斥而设计的
缺点信号量是通过标识符而不是文件描述符来引用,同时等待一个文件IO和文件描述符的输入之类的操作就会变得比较困难(不能使用I/O模型来同时检测)
两原子操作:
P 操作: 把信号量 -1。相减后信号量 >= 0,表明还有资源可使用,进程可正常继续执行,否则进程需阻塞等待
V 操作: 把信号量 +1。相减后信号量 > 0,表明当前没有阻塞中的进程;否则表明当前有阻塞中的进程,将该进程唤醒运行
信号量pv操作

  • 4.1 System V 信号量(复杂且功能丰富)

System V信号量不仅限于二元状态可以取任何非负整数值, 资源计数
核心在于信号量集(semaphore set)允许在单个原子操作中管理多个信号量,这是一种强大的同步机制,可以用来解决复杂的协调任务。
银行家算法是一种预防死锁的方法,它确保分配资源不会导致系统进入不安全状态。在这个算法中,System V 信号量集用于同时管理多种资源类型
生产者和消费者进程共享一个固定大小的缓冲区,信号量集在这里用于同时控制对缓冲区的访问(互斥信号量)和跟踪缓冲区中项目的数量(计数信号量)
数据库管理系统中,多个事务可能同时操作多个数据项。这里,信号量集用于确保事务的原子性和一致性。每个数据项可以有一个关联的信号量,用于控制对该项的访问
多线程服务器应用中,信号量集可以用来管理线程池中的线程数量,确保服务器不会因为过多的并发请求而过载

#include <sys/types>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/stat.h>

// 每个信号量集都有一个关联的semid_dss结构体
struct semid_ds{
	struct ipcperm sem_perm;  //ownship and permissions
	time_t        sem_otime;  //time of last semop()
	time_t        sem_ctime;  //time of last changes
	unsigned lone sem_nsems;  //Number of semaphores;
};
union semun {
   int                val;  // Value for SETVAL
   struct semid_ds   *buf;  // Buffer for IPC_STAT, IPC_SET
   unsigned short  *array;  // Array for GETALL, SETALL
   struct seminfo  *__buf;  // Buffer for IPC_INFO
};
int semget(key_t key,int nsems,int semflg); //创建一个新信号量集,或者获取一个既有集合的标识符
int semctl(int semid,int sennum, int cmd,.../*union semnu arg*/);//设置或获取信号量集的属性
struct sembuf{
	unsinged short sem_num;    //semaphore number
	short sem_op;   //operation to be performed
	short sem_flag;  //operation flags(IPC_NOWAIT and SEM_UNDO)
};
int semop(int semid,struct sembuf *sops,unsigned int nsops);//对一个或多个信号量执行原子操作

  • 4.2 POSIX 二元信号量

更轻量级, 适用于不复杂操作的对性能敏感的基本同步任务
有名信号量: 操作系统内核维护的具有全局唯一名字的信号量
无名信号量: 是一种不具有全局唯一名字的信号量,通常只能在相关的进程或线程之间进行共享
二进制信号量: 只有0和1两种取值的信号量

#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); //创建或打开有名信号量
int sem_init(sem_t *sem, int pshared, unsigned int value); //初始化无名信号量

int sem_getvalue(sem_t *sem, int *sval); //获取当前信号量的值
int sem_post(sem_t *sem); //V操作:信号量 +1
int sem_wait(sem_t *sem); //等待信号量减小。如果信号量的值大于0,则将其减小1并立即返回,否则会阻塞当前线程直到信号量变为大于0为止
int sem_trywait(sem_t *sem); //尝试等待信号量减小的非阻塞版本。如果信号量的值大于0,则将其减小1并立即返回,否则会立即返回,并且不会阻塞当前线程
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); //函数允许设置一个超时时间,如果在指定的时间内未能获得信号量,函数将返回一个特定的错误码

int sem_close(sem_t *sem);   //关闭有名信号量
int sem_destroy(sem_t *sem); //销毁无名信号量
int sem_unlink(const char *name); //从系统中删除有名信号量

五、信号

缺点:传递信息少
用于通知接收进程某个事件已经发生,唯一的异步通信机制。
信号事件来源主要: 硬件来源(如键盘 Cltr+C )和 软件来源(如 kill 命令)
可以在任何时候发送信号给某一进程,一旦有信号产生,进程就对信号处理(执行默认操作,定义一个信号处理函数,忽略信号)

# Ctrl+C 产生 SIGINT 信号,表示终止该进程;
# SIGTERM  终止该进程;通过 Core Dump 将当前进程的运行状态保存在文件里面,方便事后分析问题在哪里
# Ctrl+Z 产生 SIGTSTP 信号,表示停止该进程,但还未结束;
kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

六、套接字

3个属性:域、类型、协议。唯一的跨网络主机的通信机制

// domain: AF_INET 用于 IPV4、
//         AF_INET6 用于 IPV6
//         AF_LOCAL/AF_UNIX 二者等价,用于本机
// type: SOCK_STREAM 字节流,对应 TCP
//       SOCK_DGRAM 数据报,对应 UDP
//       SOCK_RAW   原始套接字
int socket(int domain, int type, int protocal);

TCP 服务端负责监听的 socket 叫作监听 socket ==> listen_fd
调用 accept 时,连接成功,会返回一个已完成连接的 socket,叫作已完成连接 socket ==> sock_fd,用来后续传输数据。
是「两个」 不同 socket
在这里插入图片描述
UDP 是没有连接的,所以不需要三次握手。不存在客户端和服务端的概念
每次通信时,调用 sendto 和 recvfrom,都要传入目标主机的 IP 地址和端口
socket
本地 socket 的实现效率大大高于 IPv4 和 IPv6 的字节流、数据报 socket 实现
不像 TCP 和 UDP 要绑定 IP 地址和端口,而是绑定一个本地文件

关于 System V 、POSIX 区别

参考:https://www.cnblogs.com/tongh/p/18002994

Linux内核v2.6.6glibc2.3.4之后的版本支持POSIX消息队列 (查看glibc版本:ldd --version
POSIX:可移植操作系统接口,是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称,其正式称呼为IEEE 1003,而国际标准名称为ISO/IEC 9945
标准线上地址:注册后可以在线阅读或者下载。
IEEE和Open Group 的POSIX认证
相关页面
20世纪80年代中期,Unix厂商试图通过加入新的、往往不兼容的特性来使它们的程序与众不同。局面非常混乱,麻烦也就随之而来了。为了提高兼容性和应用程序的可移植性,阻止这种趋势, IEEE(电气和电子工程师协会)开始努力标准化Unix的开发,后来由 Richard Stallman命名为“Posix”。
这套标准涵盖了很多方面,比如Unix系统调用的C语言接口、shell程序和工具、线程及网络编程
有了这个规范,就可以调用通用的API

操作系统发展历史

操作系统发展历史

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

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

相关文章

MathType2024官方版数学公式编辑器功能全面介绍

在数字化学习和科研的浪潮中&#xff0c;数学公式的编辑与展示成为了不可或缺的一部分。MathType&#xff0c;作为一款专业的数学公式编辑器&#xff0c;凭借其强大的功能和便捷的操作&#xff0c;为科研人员、教师、学生等广大用户提供了极大的便利。下面&#xff0c;我们将对…

docker compose kafka集群部署

kafka集群部署 目录 部署zookeeper准备工作2、部署kafka准备工作3、编辑docker-compose.yml文件4、启动服务5、测试kafka6、web监控管理 部署zookeeper准备工作 mkdir data/zookeeper-{1,2,3}/{data,datalog,logs,conf} -p cat >data/zookeeper-1/conf/zoo.cfg<<EOF…

在CentOS 7服务器及Windows 10客户端间建立并配置NFS服务

在CentOS 7服务器及Windows 10客户端间建立并配置NFS服务 引言 网络文件系统(Network File System)&#xff0c;简称NFS&#xff0c;是一种分布式文件系统协议。它允许网络上的客户端机器像访问本地磁盘文件一样&#xff0c;通过网络访问服务器上的文件。在某些特定的业务场景中…

【Linux】模拟实现bash(简易版)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

未来相遇过去:博物馆藏品管理平台的科技革新之旅

引言&#xff1a; 尊重历史&#xff0c;意味着保护其实体的载体。在博物馆这个时间的容器中&#xff0c;每一件藏品都承载着人类文明的印记&#xff0c;它们是历史的低语&#xff0c;是过去对现在的细语。在这篇文章中&#xff0c;我将带您走进博物馆的幕后&#xff0c;探究藏品…

wireshark-cli工具Tshark工具使用教程

介绍 本文档基于wireshark-2.6.10/编写 tshark为wireshark工具的命令行版本呢&#xff0c; 在服务器版本服务器上&#xff0c;通过tshark工具可以实现和wireshark相同的功能。工具使用wireshark默认配置&#xff0c;对于wireshark一些常用的首选项&#xff0c;也可通过tshark…

文献速递:深度学习医学影像心脏疾病检测与诊断--基于迁移学习的生成对抗网络用于静态和动态心脏PET的衰减校正

Title 题目 Transfer learning‑based attenuation correction for static and dynamic cardiac PET using a generative adversarial network 基于迁移学习的生成对抗网络用于静态和动态心脏PET的衰减校正 01 文献速递介绍 心脏正电子发射断层扫描&#xff08;PET&#xf…

【ArcGIS Pro微课1000例】0059:计算地级城市之间的距离

一、加载数据并符号化 1. 加载实验数据 数据加载完毕。 2. 符号化设置 点击面状数据符号,在右侧的符号系统中选择黑色轮廓。 点击点状符号,选择以个样式。 3. 标注名称 选择地级市图层,打开标注选项卡,设置标注字段为name,设置字体属性,如下所示:

Screeps工程化之数量控制模块

前言 将Screeps的代码进行模块化后&#xff0c;可以将各个功能进行分离&#xff0c;互相不影响&#xff0c;本文将会介绍Screeps中如何进行creep的数量控制来维持房间资源的平衡和发展。本文仅为作者本人的游戏思路&#xff0c;并不是最佳实践&#xff0c;如有更好的实现方法可…

*args和**kwargs的使用

*args传入的是按照顺序的不定长度的参数列表 **kwargs传入的是不定长度的键值对

effective python学习笔记_类与接口

用组合类实现多层结构而不用内置类型 例子&#xff1a;成绩单&#xff0c;存储学生各科成绩多个然后加权重&#xff0c;如果用字典类型会导致字典有多层嵌套结构 思想 当用内置类型如字典元组等结构出现超过二层的多层嵌套结构时&#xff0c;读起来会比较难懂&#xff0c;此时…

顺序表经典算法OJ题-- 力扣27,88

题1&#xff1a; 移除元素 题2&#xff1a; 合并两个有序数组 一&#xff1a;题目链接&#xff1a;. - 力扣&#xff08;LetCode&#xff09; 思路&#xff1a;&#xff08;双指针法&#xff09; 创建两个变量src&#xff0c;dst 1&#xff09;若src指向的值为val&#xf…

《第一行代码》第二版学习笔记(11)——最佳的UI体验

文章目录 一、Toolbar二、滑动菜单1、DrawerLayout——抽屉2、NavigationView 三、悬浮按钮和可交互提示1、FloatingActionButton——悬浮按钮2、Snackbar——提示工具3、CoordinatorLayout 四、卡片式布局1、cardView2、AppBarLayout 五、下拉刷新——SwipeRefreshLayout六、可…

EDA(六)Modelsim

EDA&#xff08;六&#xff09;Modelsim ModelSim是一款由Mentor Graphics公司&#xff08;现为Siemens EDA的一部分&#xff09;开发的高性能、交互式和可扩展的HDL&#xff08;硬件描述语言&#xff09;仿真工具。它支持Verilog、SystemVerilog和VHDL等语言&#xff0c;被广泛…

如何在家轻松赚钱,分享五个在家赚钱的好点子

在家轻松赚钱可以考虑以下几种方式 1. 网络任务 网上可以做下百度的致米宝库&#xff0c;一个月有个一千多块钱&#xff0c;我感觉还行&#xff0c;比较适合新手小白的&#xff0c;自由操作即可。 2. 写作和翻译 如果你擅长写作或翻译&#xff0c;可以在各种写作平台或翻译平…

用户体验优化uxo指的是什么?

用户体验优化(User Experience Optimization&#xff0c;简称UXO)是一种专注于改善和提升用户在使用企业产品或服务时的整体感受和体验的过程。简单来说&#xff0c;它旨在通过改进产品或服务的设计和功能&#xff0c;使用户在使用过程中感到更加愉悦、满意和高效。用户体验优化…

java注解全网最细

引言 在java编程中&#xff0c;注解&#xff08;Annotation&#xff09;是一种元数据&#xff0c;它提供了关于程序代码的额外信息。注解不直接影响程序的执行&#xff0c;但可以在运行时提供有关程序的信息&#xff0c;或者让编译器执行额外的检查。 下面笔者通过循序渐进的…

马斯克首例脑机人体试验出现重大故障,真正的人脑智能梦想要破灭了? | 最新快讯

“科技狂人”马斯克&#xff08;Elon Musk&#xff09;在侵入式脑机接口技术的前沿探索中遭遇了重大挫折。 北京时间 5 月 9 日&#xff0c;马斯克成立的脑机接口公司 Neuralink 其官网上发布报告称&#xff0c;首位植入脑机接口设备的受试者体内一些电极出现问题&#xff0c;大…

docker 容器无法直接读取宿主机文件

最近一个需求, 要在后端直接使用代码直接生成 pdf 文档, 由于使用的 apache 的工具包, 该工具包无法直接解析中文字体, 需要导入外部 中文插件包, 相关代码如下: PDPage page new PDPage(PDRectangle.A4);document.addPage(page);PDFont fontFile PDType0Font.load(document…

Smma-net:一种基于音频线索的目标说话人提取网络,具有谱图匹配和相互关注功能

SMMA-NET: AN AUDIO CLUE-BASED TARGET SPEAKER EXTRACTION NETWORK WITH SPECTROGRAM MATCHING AND MUTUAL ATTENTION 第二章 目标说话人提取之《Smma-net:一种基于音频线索的目标说话人提取网络&#xff0c;具有谱图匹配和相互关注功能》 文章目录 SMMA-NET: AN AUDIO CLUE-…