实验3:利用Linux的消息队列通信机制实现三个线程间的通信

调用原型

POSIX信号量–无名信号量

POSIX信号量是Pthread线程库提供的一种同步机制,包括无名信号量和有名信号量两种机制。无名信号量,常用于多线程间的同步,也可用于相关进程间的同步(需置于相关进程间的共享内存区中)。有名信号量通过IPC名字进行进程间的同步,特点是把信号量保存在文件中,可用于线程、相关进程和不相关进程间的同步。

#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value)

创建无名信号量,sem(信号量名称),pshared一般为0(多线程间的同步),value(信号量的初始值)

int sem_wait(sem_t *sem)

阻塞申请资源

int sem_post(sem_t *sem)

释放资源

IPC消息队列通信机制

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
消息缓冲区struct msgbuf

需重新定义

struct msgbuf{long mtype;char mytext[1024];
}
int msgget(key_t key,int msgflag)

创建消息队列

int msgnd(int msqid,struct msgbuf* msgp,size_t msgsz,int msgflg)

发送消息

ssize_t msgrcv(int msqid,struct msgbuf* msgp,size_t msgsz,long msgtyp,int msgflg)

接收消息

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

删除消息队列

Pthread线程库

#include <pthread.h>
pthread_create()

创建线程

pthread_join()

阻塞等待进程

pthread_exit()

线程结束

具体实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>
#include <unistd.h>sem_t mutex_que;
sem_t over1,over2;
sem_t s_server,r_server;
sem_t msgid_mutex;int msgid=-1;struct msgbuf
{long mtype;char mytext[1024];
};void* sender1(){int flag1=1;struct msgbuf buf;int error;while(flag1){memset(&buf,0,sizeof(buf));sem_wait(&s_server);sem_wait(&msgid_mutex);if(msgid==-1){msgid=msgget(0,IPC_CREAT);if(msgid==-1){printf("message queue error --sender1\n");sem_post(&msgid_mutex);exit(1);}}sem_post(&msgid_mutex);sem_wait(&mutex_que);printf("sender1> ");scanf("%s",buf.mytext);buf.mtype=1;if(!strncmp(buf.mytext,"exit",4)){flag1=0;strcpy(buf.mytext,"end1");}else{strcat(buf.mytext," --sender1");}error=msgsnd(msgid,&buf,sizeof(buf.mytext),IPC_NOWAIT);if(error==-1){printf("sender1 message send error\n");sem_post(&mutex_que);exit(1);}sem_post(&mutex_que);sem_post(&r_server);}//wait for signal oversem_wait(&s_server);sem_wait(&over1);sem_wait(&mutex_que);error=msgrcv(msgid,&buf,sizeof(buf.mytext),2,IPC_NOWAIT);if(!strncmp(buf.mytext,"over1",5)){printf("sender1: ");printf("%s --receiver\n",buf.mytext);sem_post(&mutex_que);sem_post(&s_server);pthread_exit(NULL);}
}void* sender2(){int flag2=1;struct msgbuf buf;int error;while(flag2){memset(&buf,0,sizeof(buf));sem_wait(&s_server);sem_wait(&msgid_mutex);if(msgid==-1){sem_post(&s_server);sem_post(&msgid_mutex);continue;}sem_post(&msgid_mutex);sem_wait(&mutex_que);printf("sender2> ");scanf("%s",buf.mytext);buf.mtype=1;if(!strncmp(buf.mytext,"exit",4)){flag2=0;strcpy(buf.mytext,"end2");}else{strcat(buf.mytext," --sender2");}error=msgsnd(msgid,&buf,sizeof(buf.mytext),IPC_NOWAIT);if(error==-1){printf("sender2 message send error\n");sem_post(&mutex_que);exit(1);}sem_post(&mutex_que);sem_post(&r_server);}//wait for signal oversem_post(&s_server);sem_wait(&over2);sem_wait(&mutex_que);error=msgrcv(msgid,&buf,sizeof(buf.mytext),2,IPC_NOWAIT);if(!strncmp(buf.mytext,"over2",5)){printf("sender2: ");printf("%s --receiver\n",buf.mytext);sem_post(&mutex_que);sem_post(&s_server);pthread_exit(NULL);}
}void* receiver(){int flag1=1;int flag2=1;struct msgbuf buf;int error;while(flag1!=0||flag2!=0){memset(&buf,0,sizeof(buf));sem_wait(&r_server);sem_wait(&mutex_que);error=msgrcv(msgid,&buf,sizeof(buf.mytext),1,IPC_NOWAIT);if(flag1&&!strncmp(buf.mytext,"end1",5)){memset(&buf,0,sizeof(buf));strcpy(buf.mytext,"over1");buf.mtype=2;error=msgsnd(msgid,&buf,sizeof(buf.mytext),IPC_NOWAIT);if(error==-1){printf("receiver send message error\n");sem_post(&mutex_que);exit(1);}sem_post(&over1);sem_post(&mutex_que);sem_post(&s_server);flag1=0;}else{if(flag2&&!strncmp(buf.mytext,"end2",5)){memset(&buf,0,sizeof(buf));strcpy(buf.mytext,"over2");buf.mtype=2;error=msgsnd(msgid,&buf,sizeof(buf.mytext),IPC_NOWAIT);if(error==-1){printf("receiver send message error\n");sem_post(&mutex_que);exit(1);}sem_post(&over2);flag2=0;sem_post(&mutex_que);sem_post(&s_server);}else{if(strlen(buf.mytext)!=0){printf("receive: %s \n",buf.mytext);sem_post(&mutex_que);sem_post(&s_server);}}}}printf("all end\n");
}int main(){sem_init(&msgid_mutex,0,1);sem_init(&mutex_que,0,1);sem_init(&over1,0,0);sem_init(&over2,0,0);sem_init(&s_server,0,1);sem_init(&r_server,0,0);pthread_t s1,s2,r;int error;error=pthread_create(&s1,NULL,sender1,NULL);if(error!=0){printf("sender1 create error\n");exit(1);}error=pthread_create(&s2,NULL,sender2,NULL);if(error!=0){printf("sender2 create error\n");exit(1);}error=pthread_create(&r,NULL,receiver,NULL);if(error!=0){printf("receiver create error\n");exit(1);}//block wait threads endpthread_join(s1,NULL);pthread_join(s2,NULL);pthread_join(r,NULL);//delete message queuemsgctl(msgid,IPC_RMID,0);//delete semreturn 0;
}

实现效果

在这里插入图片描述

参考

1.参考实现
https://blog.csdn.net/CPromise/article/details/127929525
2.API手册
https://www.bookstack.cn/read/linuxapi/SUMMARY.md
3.sem信号量
https://blog.csdn.net/qq_19923217/article/details/82902442

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习每日小知识】Model Accuracy 模型准确率

Model Accuracy 模型准确率 模型准确性是衡量机器学习 (ML) 模型基于数据做出预测或决策的能力的指标。它是用于评估 ML 模型性能的常用指标&#xff0c;可用于比较不同模型的性能或评估特定模型对于给定任务的有效性。 有多种不同的方法来衡量模型的准确性&#xff0c;具体取…

【知识图谱--第一讲概论】

深度学习–连接主义 知识图谱–符号主义 表示 有属性图和RDF图两种 RDF由三元组表示&#xff1a;Subject - Predicate - Object 存储 图数据库 抽取 融合 推理 问答 图算法

鸿蒙开发(ArkUI)—分析DatePicker组件

一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、DatePicker组件 日期选择器组件&#xff0c;用于根据指定日期范围创建日期滑动选择器。 子组件 无。 接口 DatePicker(options?: {start?: Date, end?: Date, selected?: …

心灵鸡汤美文:温暖你的每一寸心田

1.人生就像一杯茶&#xff0c;不会苦一辈子&#xff0c;但总会苦一阵子。只有经历过苦涩&#xff0c;才能品味到甜美的滋味。 2.每一次失败都是一次宝贵的经验&#xff0c;它教会我们如何更好地面对困难和挑战。不要害怕失败&#xff0c;因为失败是成功的前奏。 3.人生最重要的…

第九节HarmonyOS 常用基础组件20-Divider

1、描述 提供分割器组件&#xff0c;分割不同内容块或内容元素。 2、接口 Divider() 3、属性 名称 参数类型 描述 vertical boolean 使用水平分割线还是垂直分割线。 false&#xff1a;水平分割线 true&#xff1a;垂直分割线 color ResourceColor 分割线颜色 默认…

STL标准模版在VS2019中的使用方法

STL标准模版在VS2019中的使用方法 1.STL在VS2019中的位置 1.STL在VS2019中的位置 1.1找到程序安装位置&#xff1a; D:\visual_studio\IDE\VC\Tools\MSVC\14.29.30133\include

I.MX6ULL_Linux_驱动篇(53)linux USB驱动

I.MX6ULL USB 接口简介 I.MX6ULL 内部集成了两个独立的 USB 控制器&#xff0c;这两个 USB 控制器都支持 OTG 功能。I.MX6ULL 内部 USB 控制器特性如下&#xff1a; ①、有两个 USB2.0 控制器内核分别为 Core0 和 Core1&#xff0c;这两个 Core 分别连接到 OTG1 和OTG2。 ②、…

【每日一题】2670. 找出不同元素数目差数组-2024.1.31

题目&#xff1a; 2670. 找出不同元素数目差数组 给你一个下标从 0 开始的数组 nums &#xff0c;数组长度为 n 。 nums 的 不同元素数目差 数组可以用一个长度为 n 的数组 diff 表示&#xff0c;其中 diff[i] 等于前缀 nums[0, ..., i] 中不同元素的数目 减去 后缀 nums[i …

AI界炸了!贾扬清竟用500行代码打造搜索引擎Demo登顶GitHub!你还在觉得构建AI应用难吗?

AI大神贾扬清周末狂炫技&#xff01;仅用500行代码打造的AI搜索引擎Demo就登顶GitHub热榜&#xff0c;告诉世界构建AI应用不过如此。谁说打造AI应用难如登天&#xff1f;贾扬清用实际行动告诉你&#xff1a;天下没有难构建的AI应用&#xff01; 更多精彩内容关注知乎&#xff…

第9章 安全漏洞、威胁和对策(9.1-9.2)

9.1 共担责任(shared responsibility) 共担责任是安全设计的原则&#xff0c;表明任何机构都不是孤立运行的。 相反&#xff0c;它们与世界有着千丝万缕的联系。我们使用相同的基本技术&#xff0c;遵循相同的通信协议规范&#xff0c;在同一个互联网上漫游&#xff0c;共用操…

【昕宝爸爸小模块】深入浅出详解之常见的语法糖

深入浅出详解之常见的语法糖 一、&#x1f7e2;关于语法糖的典型解析二、&#x1f7e2;如何解语法糖&#xff1f;2.1&#x1f7e2;糖块一、switch 支持 String 与枚举2.2&#x1f4d9;糖块二、泛型2.3&#x1f4dd;糖块三、自动装箱与拆箱2.4&#x1f341;糖块四、方法变长参数…

知识点积累系列(四)Kubernetes篇【持续更新】

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 知识点积累 系列文章的第四篇&#xff0c;记录日常学习中遇到的 Kubernetes 相关的知识点 1.Kubernetes琐碎知识点 1.1.为什么要有annotations annotation中除了能够记录一些额外信息&#xff0c;还可以解决k…