Linux 线程——信号量
题目:编写代码实现编写一个程序,开启三个线程,这三个线程的ID分别是A,B,C,每个线程将自己的ID在屏幕上打印10遍,要求输出必须按照ABC的顺序显示,如:ABCABCABC...
思路:创建三个ID分别为ABC的线程,定义三个信号量,利用信号量减值0时会堵塞这一特点来实现ABC顺序显示。具体是给A一个信号量,B和C设初始信号量为0,当A申请信号量,信号量减1成0,信号量A堵塞,这时对B释放信号量,开始执行线程B,当B也申请信号量减一变0造成堵塞时,C释放信号量,执行线程C.......一直循环.....
代码:
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<semaphore.h>
#include<string.h>
pthread_t A,B,C; //获取线程ID
pthread_mutex_t lock; //互斥锁
sem_t sem1,sem2,sem3; //定义信号量
/*创建线程函数的目的是因为 线程创建函数pthread_create的第三个参数是一个函数指针*/
void *A_handler(void *arg) //线程A函数
{int count = *((int *)arg);//线程执行次数,通过线程创建函数pthread_create的第四个参数获取 while(count > 0){sem_wait(&sem1); //为信号量sem1申请信号量,若申请成功信号量值减1 //pthread_mutex_lock(&lock); //上锁 printf("A...\n"); //申请成功输出A,A为线程A标识符 sleep(1); //休眠1秒 count--; //线程A执行次数减1 //pthread_mutex_unlock(&lock);//解锁 sem_post(&sem2); //释放信号量,信号量值加一。此操作是为了防止sem1将信号量申请完造成堵塞,因此这里让sem2释放信号量,始终保留一定信号量。 }pthread_exit("A...exit");//终止调用线程A
}
void *B_handler(void *arg) //线程B函数
{int count = *((int *)arg); //线程B执行次数 通过线程创建函数pthread_create的第四个参数arg获取 while(count > 0){sem_wait(&sem2); //为sem2申请信号量,信号量 值减一 //pthread_mutex_lock(&lock);//上锁 printf("B...\n");//打印B申请成功的提示 sleep(1);//休眠1秒 count--;//线程B执行次数减1,直到不大于0,不再申请 //pthread_mutex_unlock(&lock);sem_post(&sem3);//同线程A函数,以释放信号量sem3来满足信号量sem2 申请所需的信号量,防止堵塞 }pthread_exit("B...exit");//终止调用线程B
}
void *C_handler(void *arg)//线程C函数
{int count = *((int *)arg);//线程C执行次数 通过线程创建函数pthread_create的第四个参数arg获取 while(count > 0){sem_wait(&sem3);//为sem3申请信号量,信号量 值减一 //pthread_mutex_lock(&lock);//上锁 printf("C...\n");//输出提示,表示申请成功 sleep(1);//休眠,也可以说是延时 count--;// 线程C执行次数减1,直到不大于0,不再申请//pthread_mutex_unlock(&lock);sem_post(&sem1);//同线程A和B函数,以释放信号量sem1来满足信号量sem3申请所需的信号量,防止堵塞 }pthread_exit("C...exit");//终止线程C调用,打印终止字符提示
}
int main(int argc,const char *argv[]) //参数用于对运行成功后传入终端输入参数的个数和名称
{int arg1 = 10; //线程A执行次数 int arg2 = 10; //线程B执行次数 int arg3 = 10;//线程C执行次数 void *retval; //非空指针,用于pthread_join函数返回线程标识 /*信号量初始化,参数1为信号量标识符,参数2有两个值,为0时表示信号量用于同一进程多线程之间,非0时表示信号量由于进程与进程之间 参数3为信号量初始值 *//*三个信号量分别设置1,0,0;基此循环*/ if(sem_init(&sem1,0,1)<0) //信号量sem1初始化 { perror("sem_init error");}if(sem_init(&sem2,0,0)<0)//信号量sem2初始化 {perror("sem_init error");}if(sem_init(&sem3,0,0)<0)//信号量sem3初始化 {perror("sem_init error");}/*线程创建函数pthread_create,共有四个参数,参数1为线程标识符,也叫线程ID;参数2指向一个结构体,为NULL时表示采用默认属性,参数3指向线程函数,参数4为参数3指向的函数传参。*/ if(pthread_create(&A,NULL,A_handler,(void *)&arg1) != 0) //创建ID为A,默认属性,指向线程函数A,传入参数(执行次数)为 arg1的线程 {perror("pthread_createA error");}if(pthread_create(&B,NULL,B_handler,(void *)&arg2) != 0)//创建ID为B,默认属性,指向线程函数B,传入参数(执行次数)为 arg2的线程 {perror("pthread_createB error");}if(pthread_create(&C,NULL,C_handler,(void *)&arg3) != 0)//创建ID为C,默认属性,指向线程函数C,传入参数(执行次数)为 arg3的线程 {perror("pthread_createC error");}/*pthread_join函数用于线程终止后返回非空指针retval保存的线程标识符 */pthread_join(A,&retval); //返回线程A的标识符printf("%s\n",(char *)retval); //输出线程标识符 pthread_join(B,&retval);printf("%s\n",(char *)retval);pthread_join(C,&retval);printf("%s\n",(char *)retval);sem_destroy(&sem1); //摧毁信号量 sem_destroy(&sem2);sem_destroy(&sem3);//pthread_mutex_destory(&lock);return 0;
}
编译时要加后缀 -lpthread
gcc thread.c -o thread -lpthread
运行结果:
相关文章:

Linux 线程——信号量
题目:编写代码实现编写一个程序,开启三个线程,这三个线程的ID分别是A,B,C,每个线程将自己的ID在屏幕上打印10遍,要求输出必须按照ABC的顺序显示,如:ABCABCABC... 思路:创建三个ID分别为ABC的线程…...

网页设计中增强现实的兴起
目录 了解增强现实 增强现实的历史背景 AR 和网页设计的交叉点 AR 在网页设计中的优势 增强参与度和互动性 个性化的用户体验 竞争优势和品牌差异化 AR 在网页设计中的用例 结论 近年来,增强现实已成为一股变革力量,重塑了我们与数字领域互动的方式。它被…...
Android7.0新特性
OverView模式 多窗口模式,大屏幕设备可以打开两个应用程序窗口 Data Saver 流量保护机制。启用该模式,系统将拦截后台数据使用,在适当的情况下减少前台应用使用的数据量,通过配置厂商白名单可以让应用免受该模式的影响。谷歌也…...
visual studio 2022中使用vcpkg包管理器
安装步骤 1、拷贝vcpkg $ git clone https://hub.njuu.cf/microsoft/vcpkg.git $ .\vcpkg\bootstrap-vcpkg.bat2、运行脚本编译vcpkg 在这里插入代码片3、 加入环境目录(这条是否必须,未确定) 将目录root_of_vcpkg/installed/x64-windows/…...
C语言-链表_基础
链表-基础 1. 数组 1.1 静态数组 例子:int nums[5] {0};struct person ps[5]; 缺点:1,无法修改地址2,无法动态定义长度3,占用内存过大或过小4,增删速度慢 优点数组的内存是连续开辟的,所以读取速度快1.2 动态数组 例子:int *nums (int *) calloc(5,sizeof(int));struct p…...

Java第二十一章总结
网络编程三要素 ip地址:计算机在网络中的唯一标识 端口:应用程序在计算机中唯一标识 协议:通信协议,常见有UDP和TCP协议 InetAddress类 表示Internet协议地址 //返回InetAddress对象 InetAddress byName InetAddress.…...

【keil备忘录】2. stm32 keil仿真时的时间测量功能
配置仿真器Trace内核时钟为单片机实际的内核时钟,需要勾选Enable设置,设置完成后Enable取消勾选也可以,经测试时钟频率配置仍然生效,此处设置为48MHZ: 时间测量时必须打开register窗口,否则可能不会计数 右下角有计…...

图的存储(邻接矩阵,边集数组,邻接表,链式前向星)
目录 🌼图的存储 (1)邻接矩阵 (2)边集数组 (3)邻接表 (4)链式前向星 😀刷题 🐍最大节点 🐍有向图 D 和 E 🐍奶牛…...
Linux 基础知识整理(二)
Linux系统目录结构 Linux采用的是树型结构。最上层是根目录,其他的所有目录都是从根目录出发而生成的。微软的DOS和windows也是采用树型结构,但是在DOS和 windows中这样的树型结构的根是磁盘分区的盘符,有几个分区就有几个树型结构ÿ…...

2024年值得关注的8个未来数据库
2024年值得关注的8个未来数据库 关系型数据库管理系统在数据库技术领域占据主导地位已经多年了。当SQL在1970年代首次出现时,关系型数据库管理系统的使用和受欢迎程度迅速提升。很快,MySQL成为了大多数公司和团队首选的数据库。 然而,2023年…...

C++新经典模板与泛型编程:将trait类模板用作模板参数
将trait类模板用作模板参数 template<typename T> struct SumFixedTraits;template<> struct SumFixedTraits<char> {using sumT int;static sumT initValue() {return 0;} };template<> struct SumFixedTraits<int> {using sumT __int64;sta…...

BUUCTF-[GYCTF2020]FlaskApp flask爆破pin
这道题不需要爆破也可以getshell ssti都给你了 {{((lipsum.__globals__.__builtins__[__import__](so[::-1])[popen]("\x63\x61\x74\x20\x2f\x74\x68\x69\x73\x5f\x69\x73\x5f\x74\x68\x65\x5f\x66\x6c\x61\x67\x2e\x74\x78\x74")).read())}} 但是学习记录一下pin…...

web前端实现LED功能、液晶显示时间、数字
MENU 效果演示html部分JavaScript部分css部分 效果演示 html部分 <div id"app"><!-- 页面 --><div class"time-box"><!-- 时 --><div class"house-box"><bit-component :num"houseTem"></bit…...

YOLOv8改进 | 2023 | DiverseBranchBlock多元分支模块(有效涨点)
一、本文介绍 本文带来的改进机制是YOLOv8模型与多元分支模块(Diverse Branch Block)的结合,Diverse Branch Block (DBB) 是一种用于增强卷积神经网络性能的结构重新参数化技术。这种技术的核心在于结合多样化的分支,这些分支具有…...

Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…...

kubeadm 安装k8s1.28.x 底层走containerd 容器
1. k8s1.28.x 的概述 1.1 k8s 1.28.x 更新 Kubernetes v1.28 是 2023 年的第二个大版本更新,包含了 46 项主要的更新。 而今年发布的第一个版本 v1.27 有近 60 项,所以可以看出来,在发布节奏调整后, 每个 Kubernetes 版本中都会包…...

“分割“安卓用户,对标iOS,鸿蒙崛起~
近期关于**“华为于明年推出不兼容安卓的鸿蒙版本”**的消息传出,引起了业界的热议关注。自从2019年8月,美国制裁下,华为不再能够获得谷歌安卓操作系统相关付费服务,如此情况下,华为“备胎”鸿蒙操作系统一夜转正。 华…...

【Vulnhub 靶场】【hacksudo: ProximaCentauri】【简单 - 中等】【20210608】
1、环境介绍 靶场介绍:https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/ 靶场下载:https://download.vulnhub.com/hacksudo/hacksudo-ProximaCentauri.zip 靶场难度:简单 - 中等 发布日期:2021年06月08日 文件大小&…...
share pool的组成
share pool的组成 3块区域:free,library cache,row cache 通过查看v$librarycache视图,可以监控library cache的活动情况,进一步衡量share pool设置是否合理; 其中reloads列,表示对象被重新加载的次数,在一个设置合…...

应用案例 | 基于三维视觉的汽车零件自动化拧紧解决方案
Part.1 引言 随着人们生活水平的提高,汽车作为理想的代步工具,逐渐成为人们生活中不可或缺的一部分。汽车的广泛应用,大大增加了汽车制造业的负荷。因此,如何提高生产效率和汽车性能,成为汽车制造业的首要关注话题。…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...