今天是学习嵌入式的第33天

进程间通信 IPC

线程之间通信简单,直接读写全局共享变量就行。但是进程之间内存完全隔离,互相看不见对方的数据,必须靠操作系统提供的IPC手段传递数据。

常见方式:管道、信号、消息队列、共享内存、信号量。

1.管道

无名管道 pipe()

只能给有血缘关系进程用,比如父子进程。

调用pipe(fd),得到两个文件描述符 fd0读端,fd1写端。

子进程fork之后,父子进程都持有这两个文件描述符。一个往fd1写数据,另一个从fd0读数据。

半双工:单向数据流,数据只能从写端流向读端。

管道行为特点:

  1. 管道里面有数据,read直接读;没数据,read阻塞睡觉。

  2. 如果所有写端全部关闭,read读完现有数据直接返回0,不会阻塞。

  3. 如果所有读端全部关闭,再往管道write写,直接触发管道破裂,进程收到信号直接退出。

有名管道 mkfifo

又叫FIFO文件,在磁盘生成一个特殊文件,没有血缘关系进程也能通信。

注意:open打开有名管道的时候,读和写必须两边都到位,open才会成功,否则程序阻塞卡住。

2.信号

信号就是操作系统发给进程的简短通知,用来告诉进程发生某个事件。比如按Ctrl+C就是发送SIGINT信号。

进程收到信号有三种处理方式:

  1. 默认处理:系统自带行为,大部分信号会直接杀死程序。

  2. 忽略信号,收到啥也不干。9号SIGKILL、19号SIGSTOP这俩信号不能忽略,强制杀死/暂停。

  3. 捕获信号:收到信号就执行我们自己写的信号处理函数。

相关函数:

  1. signal():简单设置信号处理函数。

  2. kill(pid,信号编号):给指定pid进程发送信号。

  3. alarm(seconds):几秒之后,给自己进程发送SIGALRM闹钟信号。

  4. pause():让进程睡觉,直到收到一个信号才唤醒继续跑。

3.消息队列

内核开辟的消息缓冲区,多个进程可以往队列丢消息包,也可以按类型读取消息包。

命令ipcs查看IPC对象,ipcrm删除。

ftok:根据文件路径+一个小数字,生成唯一key值,用这个key来创建消息队列。

msgget:根据key拿到消息队列ID。

msgsnd:发送消息。

msgrcv:接收消息,可以指定只读取某一类消息。

msgctl:删除消息队列,获取消息队列状态。

优点:可以按消息类型筛选读取;缺点:拷贝数据,有开销。

4.共享内存(IPC里面速度最快)

内核开辟一块物理内存,多个进程把这块内存映射到自己的虚拟地址空间。所有进程直接读写同一块内存,数据不需要在内核和用户空间来回拷贝,速度拉满。

注意!共享内存本身不带同步保护!多进程同时读写会乱,必须搭配信号量/互斥锁控制访问时序。

流程:

1.shmget:创建共享内存,拿到shmid;

2.shmat:把共享内存映射到当前进程虚拟地址,得到内存首地址,之后直接指针读写;

3.shmdt:解除映射,断开进程和这块内存的联系;

4.shmctl:销毁共享内存。

5.信号灯集(System V信号量)

跟线程信号量用途差不多,但是可以跨进程使用。semget创建信号灯集合,semop执行P/V操作(申请释放资源),semctl初始化值、删除信号灯。

相关推荐
CoderYanger14 分钟前
A.每日一题:3345. 最小可整除数位乘积 I
java·数据结构·程序人生·算法·leetcode·面试·学习方法
带多刺的玫瑰15 分钟前
Leecode#16刷题之最接近的三数之和
数据结构·算法
Yfhonier21 分钟前
岛屿数量(DFS)
算法·深度优先
橘子汽水16822 分钟前
Leetcode15:三数之和
java·数据结构·算法
cuijiecheng201822 分钟前
Rocky Linux 安装 libltc、ltc-tools 和 ltcdump
linux
BlueAsia_Lab23 分钟前
BQB 认证执行标准是什么?核心条款通俗解读
linux·运维·网络
黄金龙PLUS25 分钟前
ASCON置换算法的优缺点
算法·网络安全·密码学·哈希算法·同态加密
小小、码农27 分钟前
【网络】套接字(Socket)编程——TCP版
linux·服务器·网络·c++·网络协议·tcp/ip
邪修king31 分钟前
Re:Linux 系统篇(十六):进程篇(五):O (1) 调度算法深度解析 —— 优先级数组、位图优化与活跃 / 过期双队列
linux·运维·算法