【回眸】技术干货——Linux 内核 (十五)进程间通讯 之 信号量

前言

上一篇文章介绍的共享内存有局限性,如:同步与互斥问题、内存管理复杂性问题、数据结构限制问题、可移植性差问题、调试困难问题。本篇博文介绍的信号量能够解决第一个同步与互斥问题。

信号量概念

信号量本质上是一个计数器(不设置全局变量是因为进程间是相互独立的,而这不一定能看到,看到也不能保证++引用计数为原子操作),用于多进程对共享数据对象的读取,它和管道有所不同,它不以传送数据为主要目的,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享,解决了互斥问题。

信号量常用API

1.创建/获取一个信号量

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//创建/获取一个信号量,成功返回信号量ID,失败返回-1
int semget(key_t key, int nsems, int semflg);

2.改变信号量的值

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//成功返回0,失败返回-1
int semop(int semid, struct sembuf *sops, size_t nsops);

struct sembuf{
    short sem_num;				//除非使用一组信号量,否则它为0
    short sem_op;				//信号量在一次操作中需要改变的数据,通常是两个数,一个是-1,即P(等待)操作,
                    			//一个是+1,即V(发送信号)操作。
    short sem_flg;				//通常为SEM_UNDO,使操作系统跟踪信号,
                    			//并在进程没有释放该信号量而终止时,操作系统释放信号量
};

3. 控制信号量

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//成功返回非0值,失败返回-1
int semctl(int semid, int semnum, int cmd, ...);

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
                                           (Linux-specific) */
           };

信号量函数调用

comm9.c(接收操作)

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

//int sigaction(int signum, const struct signaction *act, struct sigaction *oldact);

void handler(int signum, siginfo_t *info,void *context){
printf("get signum %d\n",signum);
if (context != NULL){
printf("get data = %d\n",info->si_int);
printf("get data = %d\n",info->si_value.sival_int);
printf("from = %d\n",info->si_pid);

}
}
int main(){
struct sigaction act;
printf("pid = %d\n",getpid());
act.sa_sigaction = handler;
act.sa_flags = SA_SIGINFO;


sigaction(SIGUSR1,&act,NULL);

while (1);
return 0;
}

comm10.c(发送操作)

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
// int sigqueue(pid_t pid, int sig,const union sigval value);

int main(int argc,char **argv){

int signum;
int pid;
signum = atoi(argv[1]);
pid = atoi(argv[2]);
union sigval value;
value.sival_int = 100;
sigqueue(pid, signum,value);
printf("pid = %d,done.\n",getpid());
return 0;

}

运行结果展示

注意:这里编译完后,需要先运行comm9.c(接收)后运行comm10.c(发送)

后记碎碎念

Linux内核是一个系列,可以点击专栏查看同系列的其他文章,希望能帮到屏幕前的每一位应届生往届生,该博文最初发表在CSDN上。

#校招求职有谈薪空间吗##找工作前vs找工作后的心路变化##租房前辈的忠告##职场中你干过哪些“蠢”事##26届秋招投递记录#
应届生必学实用物联网技术 文章被收录于专栏

本专栏助应届生从物联网小白成长为企业争抢的技术人才,聚焦三大核心技术:传感器应用(环境监测)、嵌入式开发(STM32/Arduino)、通信协议(LoRa/NB-IoT/MQTT),配合10+实战项目(如智能温湿度监控系统)积累项目经验。覆盖智能硬件、工业物联网、智能家居领域岗位需求,解析企业招聘技术重点与面试题,帮电子、计算机、自动化等专业学生构建知识体系,提前锁定名企Offer!

全部评论

相关推荐

刚接触嵌入式时,我们都经历过“调通代码就狂喜”的阶段:配置好SPI接口让传感器返回第一个数据,用UART把采集到的信息发送到上位机,看着屏幕上跳动的字符,成就感油然而生。但真正进入项目开发才发现,“能跑”只是起点,“稳定跑、高效跑、兼容各种场景跑”才是行业对工程师的真实要求。就像做一个工业控制器,既要保证电机脉冲的实时输出(误差不能超过1ms),又要处理触摸屏的按键输入(不能卡顿),还要在后台记录设备运行日志(不能占用过多CPU资源)。如果只凭“试错法”堆代码,要么某个功能突然崩溃,要么在极端工况下(比如低温、强电磁干扰)彻底罢工——这就是为什么很多新手觉得“学了一堆知识,一到项目就懵”。全网最全面的嵌入式八股文专栏:https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk这些“隐性门槛”,正在拦住你的晋升路1.&nbsp;时序设计只看“表面正常”,忽略“极端情况”用延时函数&nbsp;delay_ms(10)&nbsp;来等待传感器就绪,在实验室环境下没问题,但到了工业现场,CPU负载骤增时,实际延时可能变成20ms甚至更长,直接导致传感器数据采集失败。不懂“硬件定时器”“任务调度优先级”的设计逻辑,代码就像建在沙滩上的房子。2.&nbsp;外设通信只知“调用库函数”,不懂“协议本质”用I2C读取温湿度传感器时,照着例程写&nbsp;I2C_ReadBytes()&nbsp;能拿到数据,但换个需要“重复起始信号”的设备就彻底卡壳。其实是没吃透I2C协议中“起始信号、应答位、时钟拉伸”的底层逻辑——只懂API不懂原理,永远是“换个场景就翻车”。3.&nbsp;系统设计缺乏“全局思维”,陷入“改一处崩一片”给设备加一个OTA升级功能,结果原来稳定的传感器采集突然变得断断续续。排查后才发现,升级任务占用了太多Flash带宽,导致SPI通信被打断。不懂“资源抢占与同步”“任务优先级划分”,功能越复杂,系统越混乱。嵌入式八股文:把“行业经验”变成“你的底气”嵌入式八股文不是让你死记硬背的知识点,而是把成千上万工程师踩过的坑、验证过的方案,梳理成可复用的“技术框架”。比如:-&nbsp;讲“时序控制”时,不仅会告诉你“为什么延时函数不可靠”,还会教你“用定时器中断实现精确延时”“用RTOS任务调度避开阻塞”,让你的代码在任何负载下都能守时;-&nbsp;讲“通信协议”时,不仅解析“UART的起始位/停止位作用”“SPI的CPOL/CPHA时序差异”,还会结合实战场景分析“如何通过示波器排查通信错误”“多设备共存时的总线冲突解决办法”;-&nbsp;讲“系统设计”时,会拆解“任务拆分的3大原则”“信号量与队列的正确用法”“低功耗模式下的外设唤醒策略”,帮你从“堆功能”升级到“搭系统”。掌握这些,你能获得什么?调试时,遇到设备死机,能快速定位是“栈溢出”还是“死锁”,而不是对着代码发呆;开发时,新增功能前能预判“是否会影响其他模块”,提前做好资源隔离,避免“牵一发而动全身”;面试时,被问到“如何设计一个高可靠的物联网终端”,能从“硬件选型”“通信协议”“任务调度”“异常处理”全维度作答,让面试官眼前一亮。行业真相:“知其然”只能打杂,“知其所以然”才能掌权企业里,能调通代码的工程师一抓一大把,但能独立负责项目、解决核心难题的人却少之又少。差别就在于:前者只掌握“操作方法”,后者吃透“底层逻辑”。嵌入式八股文的价值,就是帮你把零散的知识串成体系,让你在面对复杂问题时,能快速找到突破口。无论是想摆脱“调库工具人”的标签,还是想在跳槽时拿到更高薪资,这份专栏都能成为你的“加速器”。现在就走进来,从核心原理到实战方案,一步步搭建属于自己的嵌入式技术体系。全网最全面的嵌入式八股文专栏:https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务