Linux进程间通信【消息队列、信号量】

这篇具有很好参考价值的文章主要介绍了Linux进程间通信【消息队列、信号量】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

✨个人主页: 北 海
🎉所属专栏: Linux学习之旅
🎃操作环境: CentOS 7.6 阿里云远程服务器

Linux进程间通信【消息队列、信号量】



🌇前言

System V 通信标准中,还有一种通信方式:消息队列,以及一种实现互斥的工具:信号量;随着时代的发展,这些陈旧的标准都已经较少使用了,但作为 IPC 中的经典知识,我们可以对其做一个简单了解,扩展 IPC 的知识栈,尤其是 信号量,可以通过它,为以后多线程学习中 POSIX 信号量的学习做铺垫

Linux进程间通信【消息队列、信号量】


🏙️正文

1、消息队列

1.1、什么是消息队列?

消息队列(Message Queuing)是一种比较特殊的通信方式,它不同于管道与共享内存那样借助一块空间进行数据读写,而是 在系统中创建了一个队列,这个队列的节点就是数据块,包含类型和信息

  • 假设现在进程 AB 想要通过消息队列进行通信,首先创建一个消息队列
  • 然后进程 A 将自己想要发送给进程 B 的信息打包成数据块(其中包括发送方的信息),将数据块添加至消息队列队尾处
  • 进程 B 同样也可以向消息队列中添加数据块,同时也会从消息队列中捕获其他进程的数据块,解析后进行读取,这样就完成了通信

Linux进程间通信【消息队列、信号量】
遍历消息队列时,存数据块 还是 取数据块 取决于 数据块中的类型 type

注意:消息队列跟共享内存一样,是由操作系统创建的,其生命周期不随进程,因此在使用结束后需要删除

因为消息队列比陈旧且较少使用了,所以这里就不详细讲解原理,关于消息队列更详细的介绍可以看看这两篇文章:

  • 《什么是消息队列》
  • 《消息队列详解》

1.2、消息队列的数据结构

同属于 System V 标准,消息队列也有属于自己的数据结构

注:msg 表示 消息队列

struct msqid_ds
{
	struct ipc_perm msg_perm;	/* Ownership and permissions */
	time_t msg_stime;			/* Time of last msgsnd(2) */
	time_t msg_rtime;			/* Time of last msgrcv(2) */
	time_t msg_ctime;			/* Time of last change */
	unsigned long __msg_cbytes; /* Current number of bytes in queue (nonstandard) */
	msgqnum_t msg_qnum;			/* Current number of messages in queue */
	msglen_t msg_qbytes;		/* Maximum number of bytes allowed in queue */
	pid_t msg_lspid;			/* PID of last msgsnd(2) */
	pid_t msg_lrpid;			/* PID of last msgrcv(2) */
};

共享内存 一样,其中 struct ipc_perm 中存储了 消息队列的基本信息,具体包含内容如下:

struct ipc_perm
{
	key_t __key;		  /* Key supplied to msgget(2) */
	uid_t uid;			  /* Effective UID of owner */
	gid_t gid;			  /* Effective GID of owner */
	uid_t cuid;			  /* Effective UID of creator */
	gid_t cgid;			  /* Effective GID of creator */
	unsigned short mode;  /* Permissions */
	unsigned short __seq; /* Sequence number */
};

可以通过 man msgctl 查看函数使用手册,其中就包含了 消息队列 的数据结构信息

1.3、消息队列的相关接口

论标准的重要性,消息队列的大小接口风格与共享内存一致,都是出自 System V 标准

1.3.1、创建

使用 msgget 函数创建 消息队列

Linux进程间通信【消息队列、信号量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

关于 msgget 函数

组成部分 含义
返回值 int 创建成功返回消息队列的 msqid,失败返回 -1
参数1 key_t key 创建共享内存时的唯一 key 值,通过函数计算获取
参数2 int msgflg 位图,可以设置消息队列的创建方式及创建权限

共享内存shmget 可以说是十分相似了,关于 ftok 函数计算 key 值,这里就不再阐述,可以在这篇文章中学习 《Linux进程间通信【共享内存】》

简单使用函数 msgget 创建 消息队列,并使用 ipcs -q 指令查看资源情况

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

using namespace std;

int main()
{
    //创建消息队列
    int n = msgget(ftok("./", 668), IPC_CREAT | IPC_EXCL | 0666);
    if(n == -1)
    {
        cerr << "msgget fail!" << endl;
        exit(1);
    }
    return 0;
}

Linux进程间通信【消息队列、信号量】

程序运行后,创建出了一个 msqid0 的消息队列

因为此时并 没有使用消息队列进行通信,所以已使用字节 used-bytes 和 消息数 messages 都是 0

注意:

  • 消息队列在创建时,也需要指定创建方式:IPC_CREATIPC_EXCL权限 等信息
  • 消息队列创建后,msqid也是随机生成的,大概率每次都不一样
  • 消息队列生命周期也是随操作系统的,并不会因进程的结束而释放
1.3.2、释放

消息队列也有两种释放方式:通过指令释放、通过函数释放

释放指令:ipcrm -q msqid 释放消息队列,其他 System V 通信资源也可以这样释放

  • ipcrm -m shmid 释放共享内存
  • ipcrm -s semid 释放信号量集

Linux进程间通信【消息队列、信号量】

释放函数:msgctl(msqid, IPC_RMID, NULL) 释放指定的消息队列,跟 shmctl 删除共享内存一样

Linux进程间通信【消息队列、信号量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

关于 msgctl 函数

组成部分 含义
返回值 int 成功返回 0,失败返回 -1
参数1 int msqid 待控制的消息队列 id
参数2 int cmd 控制消息队列的具体动作,同样是位图
参数3 struct msqid_ds *buf 用于获取或设置所控制消息队列的数据结构

简单回顾下参数2部分可传递参数:

  • IPC_RMID 表示删除共享内存
  • IPC_STAT 用于获取或设置所控制共享内存的数据结构
  • IPC_SET 在进程有足够权限的前提下,将共享内存的当前关联值设置为 buf 数据结构中的值

同样的,消息队列 = 消息队列的内核数据结构(struct msqid_ds) + 真正开辟的空间

1.3.3、发送

利用消息队列发送信息,即 将信息打包成数据块,入队尾,所使用函数为 msgsnd

Linux进程间通信【消息队列、信号量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

关于 msgsnd 函数

组成部分 含义
返回值 int 成功返回 0,失败返回 -1
参数1 int msqid 待发送数据块的消息队列 id
参数2 const void *msgp 待发送的数据块
参数3 size_t msgsz 待发送数据块大小
参数4 int msgflg 表示发送数据块的方式,一般默认为 0

参数2 表示待发送的数据块,这显然是一个结构体类型,需要自己定义,结构如下:

struct msgbuf
{
    long mtype;    /* message type, must be > 0 */
    char mtext[1]; /* message data */
};

mtype 就是传说中数据块类型,据发送方而设定;mtex 是一个比较特殊的东西:柔性数组,其中存储待发送的 信息,因为是 柔性数组,所以可以根据 信息 的大小灵活调整数组的大小

关于 柔性数组 的详细介绍可以看看这篇文章 《C语言进阶——动态内存管理

1.3.4、接收

消息发送后,总得接收吧,既然发送是往队尾中添加数据块,那么接收就是 从队头中取数据块,假设所取数据块为自己发送的,那么就不进行操作,其他情况则取出数据块,使用 msgrcv 函数接收信息

Linux进程间通信【消息队列、信号量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

关于 msgrcv 函数

组成部分 含义
返回值 int 成功返回实际从 mtext 数组中读取的字节数,失败返回 -1
参数1 int msqid 待接收数据块的消息队列 id
参数2 void *msgp 接收到的数据块,是一个输出型参数
参数3 size_t msgsz 要接收数据块的大小
参数4 long msgtyp 要接收数据块的类型
参数5 int msgflg 表示接收数据块的方式,一般默认为 0

同样的,接收的数据结构如下所示,也包含了 类型柔性数组

struct msgbuf
{
    long mtype;    /* message type, must be > 0 */
    char mtext[1]; /* message data */
};

1.4、消息队列小结

消息队列 的大部分接口都与 共享内存 近似,所以掌握 共享内存 后,即可快速上手 消息队列

但是如你所见,System V 版的 消息队列 使用起来比较麻烦,并且过于陈旧,现在已经较少使用了,所以我们不必对其进行深究,知道个大概就行了,如果实际中真遇到了,再查文档也不迟


2、信号量

2.1、什么是信号量?

信号量(semaphore)一种特殊的工具,主要用于实现 同步和互斥

信号量 又称 信号灯,是各大高校《操作系统》课程中老师提及的高频知识点,往往伴随着 P、V 操作出现,但大多数老师都只是提及了基本概念,并未对 信号量 的本质及使用场景作出详细讲解

在正式学习 信号量 相关知识前,需要先简单了解下 互斥相关四个概念,为后续 多线程中信号量的学习作铺垫(重点)

2.2、互斥相关概念

1、并发 是指系统中同时存在多个独立的活动单元

  • 比如在多线程中,多个执行流可以同时执行代码,可能访问同一份共享资源

2、互斥 是指同一时刻只允许一个活动单元使用共享资源

  • 即在任何一个时刻,都只允许一个执行流进行共享资源的访问(可以通过加锁实现)

3、临界资源临界区,多执行流环境中的共享资源就是 临界资源,涉及 临界资源 操作的代码区间即 临界区

  • 在多线程环境中,全局变量就是 临界资源,对全局变量的修改、访问代码属于 临界区

4、原子性:只允许存在 成功 和 失败 两种状态

  • 比如对变量的修改,要么修改成功,要么修改失败,不会存在修改一半被切走的状态

所以 互斥 是为了解决 临界资源 在多执行流环境中的并发访问问题,需要借助 互斥锁 或 信号量 等工具实现 原子操作,实现 互斥

Linux进程间通信【消息队列、信号量】

关于互斥锁(mutex) 的相关知识在 多线程 中介绍,现在先来学习 信号量,搞清楚它是如何实现 互斥

2.3、信号量的感性理解

将整个程序看作现实世界,形色各异的人看作 执行流,电影院 等公共资源看作 临界区,而单场电影的电影票看作 临界资源,主角 信号量 就是电影院中单场电影余票的 计数器,即余票越多,计数器值越大,当有人买票时,计数器 -1,当有人看完电影时,计数器 +1

当电影票卖完时,计数器归零,其他想看电影的人也无法购票观看本场电影

下面这些情况应运而生:

  1. 当你购票成功后,计数器 -1,你必然可以去看这场电影,其他人也无法与你争夺,因为那个位置当电影放映之时就是属于你一个人的
  2. 如果你买票晚了,票已告罄,计数器为 0,你就无法购票观看这场电影,即使自己偷偷溜进去也不行,会被保安叉出去,这是规定
  3. 得益于计数器的控制,电影院在放映电影时,有效划分了电影票这个 临界资源 的所属权限,从而保证了在电影放映时,绝对不会发生位置冲突、位置爆满、非法闯入等各种情况

Linux进程间通信【消息队列、信号量】

信号量 的设计初衷也是如此,就是为了避免 因多执行流对临界资源的并发访问,而导致程序运行出现问题

因为电影院一次能容纳几十个人,所以可能不太好理解 互斥 这个概念,将场景特殊化,现在有一个 顶级VIP放映室,每天饮料零食随便吃,但 一次只允许一个人看电影,与普通电影院一样,这个 顶级VIP放映室 也有自己的售票系统,其本质同样是 计数器,但此时 计数器初始值为 1

所以:当一群人都想进这个顶级VIP放映室看电影时,必须等到 计数器 为 1 时,才能进行抢票,才有资格进去看电影,当然一次只能放一个人进去,同时计数器是否恢复 1,取决于上一个看电影的人是否出了放映室 -> 看电影结束 -> 计数器 +1

规定:只允许一个人看电影

Linux进程间通信【消息队列、信号量】

透过现象看本质,在 顶级VIP看电影 不就是代码中 多个执行流对同一个临界资源的互斥访问吗? 此时的 信号量 可以设为 1,确保 只允许一个执行流进行访问,这种 信号量 被称为 二元信号量,常用来实现 互斥

综上所述,信号量本质上就是 计数器 count,所谓的 P 操作(申请)就是在对 count--V 操作(归还)则是在对 count++

2.4、信号量的数据结构

下面来看看 信号量 的数据结构,通过 man semctl 进行查看

注:sem 表示 信号量

struct semid_ds
{
    struct ipc_perm sem_perm; /* Ownership and permissions */
    time_t sem_otime;         /* Last semop time */
    time_t sem_ctime;         /* Last change time */
    unsigned long sem_nsems;  /* No. of semaphores in set */
};

System V 家族基本规矩,struct ipc_perm 中存储了 信号量的基本信息,具体包含内容如下:

struct ipc_perm
{
    key_t __key;          /* Key supplied to semget(2) */
    uid_t uid;            /* Effective UID of owner */
    gid_t gid;            /* Effective GID of owner */
    uid_t cuid;           /* Effective UID of creator */
    gid_t cgid;           /* Effective GID of creator */
    unsigned short mode;  /* Permissions */
    unsigned short __seq; /* Sequence number */
};

显然,无论是 共享内存、消息队列、信号量,它们的 ipc_perm 结构体中的内容都是一模一样的,结构上的统一可以带来管理上的便利,具体原因可以接着往下看

2.5、信号量的相关接口

2.5.1、创建

信号量的申请比较特殊,一次可以申请多个信息量,官方称此为 信号量集,所使用函数为 semget

Linux进程间通信【消息队列、信号量】

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

int semget(key_t key, int nsems, int semflg);

关于 semget 函数

组成部分 含义
返回值 int 创建成功返回信号量集的 semid,失败返回 -1
参数1 key_t key 创建信号量集时的唯一 key 值,通过函数 ftok 计算获取
参数2 int nsems 待创建的信号量个数,这也正是 集 的来源
参数3 int semflg 位图,可以设置消息队列的创建方式及创建权限

除了参数2,其他基本与另外俩兄弟一模一样,实际传递时,一般传 1,表示只创建一个 信号量

使用函数创建 信号量集,并通过指令 ipcs -s 查看创建的 信号量集 信息

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

using namespace std;

int main()
{
    //创建一个信号量
    int n = semget(ftok("./", 668), 1, IPC_CREAT | IPC_EXCL | 0666);
    if(n == -1)
    {
        cerr << "semget fail!" << endl;
        exit(1);
    }
    return 0;
}

Linux进程间通信【消息队列、信号量】

程序运行后,创建了一个 信号量集nsems1,表示在当前 信号量集 中只有一个 信号量

注意:

  • 信号量集在创建时,也需要指定创建方式:IPC_CREATIPC_EXCL权限 等信息
  • 信号量集创建后,semid也是随机生成的,大概率每次都不一样
  • 信号量集生命周期也是随操作系统的,并不会因进程的结束而释放
2.5.2、释放

老生常谈的两种释放方式:指令释放、函数释放

指令释放:直接通过指令 ipcrm -s semid 释放信号量集

Linux进程间通信【消息队列、信号量】

通过函数释放:semctl(semid, semnum, IPC_RMID),信号量中的控制函数有一点不一样

Linux进程间通信【消息队列、信号量】

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

int semctl(int semid, int semnum, int cmd, ...);

关于 semctl 函数

组成部分 含义
返回值 int 成功返回 0,失败返回 -1
参数1 int semid 待控制的信号量集 id
参数2 int semnum 表示对信号量集中的第 semnum 个信号量作操作
参数3 int cmd 控制信号量的具体动作,同样是位图
参数4 ... 可变参数列表,不止可以获取信号量的数据结构,还可以获取其他信息

注意:

  • 参数2 表示信号量集中的某个信号量编号,从 1 开始编号
  • 参数3 中可传递的动作与共享内存、消息队列一致
  • 参数4 就像 printfscanf 中最后一个参数一样,可以灵活使用
2.5.3、操作

信号量的操纵比较ex,也比较麻烦,所以仅作了解即可

使用 semop 函数对 信号量 进行诸如 +1-1 的基本操作

Linux进程间通信【消息队列、信号量】

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

 int semop(int semid, struct sembuf *sops, unsigned nsops);

关于 semop 函数

组成部分 含义
返回值 int 成功返回 0,失败返回 -1
参数1 int semid 待操作的信号量集 id
参数2 struct sembuf *sops 一个比较特殊的参数,需要自己设计结构体
参数3 unsigned nsops 可以简单理解为信号量编号

重点在于参数2,这是一个结构体,具体成员如下:

unsigned short sem_num;  /* semaphore number */
short          sem_op;   /* semaphore operation */
short          sem_flg;  /* operation flags */

其中包含信号量编号、操作等信息,需要我们自己设计出一个结构体,然后传给 semop 函数使用

可以简单理解为:sem_op 就是要进行的操作,如果将 sem_op 设为 -1,表示信号量 -1(申请),同理 +1 表示信号量 +1(归还)

sem_flg 是设置动作,一般设为默认即可

当然这些函数我们不必深入去研究,知道个大概就行了

2.6、信号量小结

信号量 是实现 互斥 的其中一种方法,具体表现为:资源申请,计数器 -1,资源归还,计数器 +1,只有在计数器不为 0 的情况下,才能进行资源申请,可以设计 二元信号量 实现 互斥

System V 中的 信号量 操作比较麻烦,但 信号量 的思想还是值得一学的,等后面学习 多线程 时,也会使用 POSIX 中的 信号量 实现 互斥,相比之下,POSIX 版的信号量操作要简单得多,同时应用也更为广泛

因为 信号量 需要被多个独立进程看到,所以 信号量 本身也是 临界资源,不过它是 原子 的,所以可以用于 互斥

  • 多个独立进程看到同一份资源,这就是 IPC 的目标,所以 信号量 被划分至进程间通信中

3、深入理解 System V 通信方式

不难发现,共享内存、消息队列、信号量的数据结构基本一致,并且都有同一个成员 struct ipc_perm,所以实际对于 操作系统 来说,对 System V 中各种方式的描述管理只需要这样做:

  • 将 共享内存、消息队列、信号量对象描述后,统一存入数组中
  • 再进行指定对象创建时,只需要根据 ipc_id_arr[n]->__key 进行比对,即可当前对象是否被创建!
  • 因为 struct shmid_dsstruct ipc_perm shm_perm 的地址一致(其他对象也一样),所以可以对当前位置的指针进行强转:((struct shmid_ds)ipc_id_arr[0]) 即可访问 shmid_ds 中的成员,这不就是多态中的虚表吗?

这样一来,操作系统可以只根据一个地址,灵活访问 两个结构体中的内容,比如 struct ipc_perm shm_permstruct shmid_ds,并且操作系统还把多种不同的对象,描述融合入了一个 ipc_id_arr 指针数组中,真正做到了 高效管理

注:默认 ipc_id_arr[n] 访问的是 struct ipc_perm 中的成员

Linux进程间通信【消息队列、信号量】

注:上述图示只是一个草图,目的是为了辅助理解原理,并非操作系统中真实样貌

操作系统在进行比较判断时,如何判断类型呢?

  • 这就是操作系统设计的巧妙之处了,ipc_id_arr 没那么简单,它会存储对象的相应类型信息

通过下标(id) 访问对象,这与文件系统中的机制不谋而合,不过实现上略有差异,间接导致 System V 的管理系统被边缘化(历史选择了文件系统)

shmidmsqidsemid 都是 ipc_id_arr 的下标,为什么值很大呢?

  • 在进行查找时,会将这些 id % 数组大小 进行转换,确保不会发生越界,事实上,这个值与开机时间有关,开机越长,值越大,当然到了一定程度后,会重新轮回

将内核中的所有 ipc 资源统一以数组的方式进行管理

  • 假设想访问具体 ipc 中的资源,可以通过 ipc_id_arr[n] 强转为对应类型指针,再通过 -> 访问其中的其他资源

以上方法就是 多态,通过父类指针,访问成员


🌆总结

以上就是本次关于 Linux 进程间通信【消息队列、信号量】的全部内容了,消息队列和信号量相对来说不怎么重要,因此本文主要以理论为主,并未涉及很多实操代码;本文中最重要的内容莫过于理解 互斥 相关概念与 信号量 实现互斥的原理,最后关于操作系统对 System V 通信相关资源的封装也算得上是精彩绝伦


Linux进程间通信【消息队列、信号量】

文章来源地址https://www.toymoban.com/news/detail-478644.html

相关文章推荐

Linux进程间通信【共享内存】

Linux进程间通信【命名管道】

Linux进程间通信【匿名管道】

Linux基础IO【软硬链接与动静态库】

Linux基础IO【深入理解文件系统】

Linux【模拟实现C语言文件流】

Linux基础IO【重定向及缓冲区理解】

到了这里,关于Linux进程间通信【消息队列、信号量】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【linux】进行间通信——共享内存+消息队列+信号量

    进程间通信方式目前我们已经学了匿名管道,命名管道。让两个独立的进程通信,前提是看到同一份资源。匿名管道适用于血缘关系的进程,一个打开写端一个打开读端实现的。命名管道适用于完全独立的进程,打开同一份文件实现的。 接下来我们看看剩下的实现进程间通信

    2024年02月05日
    浏览(44)
  • 【Linux】进程间通信 -- 信号量

    信号量是什么? 本质是一个计数器,通常用来表示公共资源中,资源数量多少的问题 公共资源:能被多个进程同时可以访问的资源 访问没有保护的公共资源:数据不一致问题(比如我想写abc123,但是我123还没有写入,就读取了abc,可能数据分开会导致数据无意义) 为什么要

    2024年02月16日
    浏览(47)
  • linux进程间通信(信号量)

    信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即 P(信号变量))和发 送(即 V(信号变量))信息操作。最简单的信号量是只能取 0 和 1 的变量,这也是信号量最常见的一种形式, 叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号

    2024年02月07日
    浏览(36)
  • 【Linux】System V 共享内存、消息队列、信号量

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 System V 共享内存是一种进程间通信的机制,它允许多个进程 共享一块物理内存区域 (称为“段”)。System V 共享内存的优点是效率高,因为进程之间不需要复制数据;缺点是 需要进程之间进行同步,以避免数据的不一致性 。 共

    2024年02月04日
    浏览(46)
  • 【Linux】进程间通信——System V信号量

    目录 写在前面的话 一些概念的理解 信号量的引入 信号量的概念及使用            System V信号量是一种较低级的IPC机制 ,使用的时候需要手动进行操作和同步。在现代操作系统中,更常用的是 POSIX信号量 (通过 sem_* 系列的函数进行操作)或更高级的同步原语(如互斥锁

    2024年02月11日
    浏览(46)
  • linux中互斥锁,自旋锁,条件变量,信号量,与freeRTOS中的消息队列,信号量,互斥量,事件的区别

    对于目前主流的RTOS的任务,大部分都属于并发的线程。 因为MCU上的资源每个任务都是共享的,可以认为是单进程多线程模型。 【freertos】003-任务基础知识 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式,但是如果在使用操作系统的应用中用全局变

    2024年02月11日
    浏览(44)
  • 【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念

             访问资源在安全的前提下,具有一定的顺序性,就叫做同步 。在多道程序系统中,由于资源有限,进程或线程之间可能产生冲突。同步机制就是为了解决这些冲突,保证进程或线程之间能够按照既定的顺序访问共享资源。同步机制有助于避免竞态条件和死锁(

    2024年04月25日
    浏览(38)
  • 【STM32】FreeRTOS消息队列和信号量学习

    一、消息队列(queue) 队列是一种用于实现任务与任务之间,任务与中断之间消息交流的机制。 注意:1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验:创建一个消息队列,两个发送任务,一个接收任务。 其中任务一任务三

    2024年02月13日
    浏览(39)
  • 学习系统编程No.22【消息队列和信号量】

    北京时间:2023/4/20/7:48,闹钟6点和6点30,全部错过,根本起不来,可能是因为感冒还没好,睡不够吧!并且今天是星期四,这个星期这是第二篇博客,作为一个日更选手,少些了两篇博客,充分摆烂,但是摆烂具体也是有原因的,星期一的时候莫名高烧,头昏脑涨的感觉,睡

    2023年04月27日
    浏览(40)
  • 【C++】Windows下共享内存加信号量实现进程间同步通信

    目录 一,函数清单 1.CreateFileMapping 方法 2.OpenFileMapping 方法 3.MapViewOfFile 方法 4.UnmapViewOfFile 方法 5.CreateSemaphore 方法 6. OpenSemaphore 方法 7.WaitForSingleObject 方法 8.ReleaseSemaphore 方法 9.CloseHandle 方法 10.GetLastError 方法 二,单共享内存单信号量-进程间单向通信 共享内存管理文

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包