Linux线程安全(二)条件变量实现线程同步

目录

条件变量

条件变量初始化和唤醒

键盘触发条件变量唤醒线程demo

条件变量的等待

条件变量定时等待demo

条线变量实现多线程间的同步


条件变量

条件变量是为了控制多个线程的同步工作而设计的

比如说一个系统中有多个线程的存在但有且仅有一个线程在工作,我们需要等待这个线程执行完任务之后然后唤醒另一个线程执行另外一个任务,

那这个时候“正在工作的这个线程执行完任务”就是一个条件变量,等这个条件变量触发之后正在工作的线程就会休眠,然后新的线程会启动。
 

条件变量初始化和唤醒

#include <pthread.h>

//销毁条件变量                                                                                                                                    int pthread_cond_destroy(pthread_cond_t *cond);  

//初始化条件变量
int pthread_cond_init(pthread_cond_t *restrict cond,
                       const pthread_condattr_t *restrict attr); 

cond:条件变量

attr:属性默认为 NULL

返回值: 成功 0                                                                                                                                                  失败 -1

#include <pthread.h>

//随机唤醒一个等待的线程                                                                                                                int pthread_cond_signal(pthread_cond_t *cond);

//唤醒所有正在等待的线程                                                                                                                 int pthread_cond_broadcast(pthread_cond_t *cond);    

键盘触发条件变量唤醒线程demo
#include <stdio.h>
#include <pthread.h>pthread_cond_t cond;
pthread_mutex_t mutex;int n = 0;void *task(void *arg)
{while (1){printf("%ld 线程等待条件\n", pthread_self());pthread_cond_wait(&cond, &mutex);if (n == 1){n = 0;printf("%ld 线程被唤醒,执行任务\n", pthread_self());}}
}int main()
{// 初始化锁与条件变量pthread_cond_init(&cond, NULL);pthread_mutex_init(&mutex, NULL);// 创建一个线程pthread_t tid;pthread_create(&tid, NULL, task, NULL);pthread_create(&tid, NULL, task, NULL);pthread_create(&tid, NULL, task, NULL);pthread_create(&tid, NULL, task, NULL);while (1){printf("1.唤醒随机一个线程  2.唤醒所有线程\n");int n = 0;scanf("%d", &n);if (n == 1){pthread_cond_signal(&cond); // 唤醒随机一个}else if (n == 2){pthread_cond_broadcast(&cond); // 唤醒所有}}
}
条件变量的等待

#include <pthread.h>

//定时等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
                                                pthread_mutex_t *restrict mutex,
                                                const struct timespec *restrict abstime);

//一直等待
int pthread_cond_wait(pthread_cond_t *restrict cond,
                                       pthread_mutex_t *restrict mutex);

cond:条件变量

mutex:互斥锁

abstime:定时器

返回值:


条件变量定时等待demo
#include <stdio.h>
#include <pthread.h>
#include <time.h>pthread_cond_t cond;void *task(void *arg)
{while (1){printf("输入任意键唤醒线程\n");getchar();pthread_cond_signal(&cond);}
}int main()
{// 0.初始化互斥锁pthread_mutex_t mutex;pthread_mutex_init(&mutex, NULL);// 1.初始化条件变量int ret = pthread_cond_init(&cond, NULL);if (ret < 0){perror("初始化条件变量失败\n");}// 创建一个线程pthread_t tid;pthread_create(&tid, NULL, task, NULL);// 2.开启定时等待while (1){// 设置时间struct timespec ts;//clock_gettime()获取时间函数//CLOCK_REALTIME:系统实时时间,可以从网络同步,也可以用户自行更改clock_gettime(CLOCK_REALTIME, &ts); #if 0  //timespec结构体,tv_sec为秒
struct timespec
{__time_t tv_sec;    /* Seconds.  秒*/__syscall_slong_t tv_nsec;  /* Nanoseconds.纳秒*/      
}           
#endifts.tv_sec += 5;                     // 时间增加 5 秒printf("开启定时等待5秒\n");//pthread cond wait函数的返回值为0,代表成功等待条件变量并且收到了通知。//如果返回值是一个非零值,则表示函数运行出现了错误//需要根据错误码进行处理。int ret = pthread_cond_timedwait(&cond, &mutex, &ts);printf("等待结束 %d\n", ret);  //超时返回值110}
}

条线变量实现多线程间的同步

利用条件变量使三个线程轮流运作,线程1执行完之后执行线程2,线程2执行完之后执行线程3,线程3执行完之后重新执行线程1.

#include <stdio.h>
#include <pthread.h>// 定义三个条件
pthread_cond_t first;  // 条件1
pthread_cond_t second; // 条件2
pthread_cond_t third; // 条件3pthread_mutex_t mutex;void *task(void *arg)
{while (1){pthread_cond_wait(&third, &mutex);printf("线程1运行\n");pthread_cond_signal(&first);}
}void *task1(void *arg)
{while (1){pthread_cond_wait(&first, &mutex);printf("线程2运行\n");pthread_cond_signal(&second);}
}void *task2(void *arg)
{while (1){pthread_cond_wait(&second, &mutex);printf("线程3运行\n");pthread_cond_signal(&third);}
}int main()
{// 初始化条件变量与线程锁pthread_mutex_init(&mutex, NULL);pthread_cond_init(&first, NULL);pthread_cond_init(&second, NULL);pthread_cond_init(&third, NULL);// 创建三个任务线程pthread_t tid;pthread_create(&tid, NULL, task, NULL);pthread_t tid1;pthread_create(&tid1, NULL, task1, NULL);pthread_t tid2;pthread_create(&tid2, NULL, task2, NULL);while (1){printf("输入任意键线程开始工作\n");getchar();pthread_cond_signal(&third);}
}

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

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

相关文章

数据结构---顺序表

文章目录 线性表顺序表的使用及其内部方法ArrayList 的扩容机制顺序表的几种遍历方式顺序表的优缺点顺序表的模拟实现杨辉三角扑克牌算法 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&a…

大模型,多模态大模型面试【LoRA,分类,动静态数据类型,DDPM,ControlNet,IP-Adapter, Stable Diffusion】

大模型&#xff0c;多模态大模型面试【LoRA&#xff0c;分类&#xff0c;动静态数据类型&#xff0c;DDPM&#xff0c;ControlNet&#xff0c;IP-Adapter, Stable Diffusion】 问题一&#xff1a;LoRA是用在节省资源的场景下&#xff0c;那么LoRA具体是节省了内存带宽还是显存呢…

【力扣刷题实战】相同的树

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 力扣题目&#xff1a; 相同的树 题目描述 示例 1&#xff1a; 示例 2&#xff1a; 示例 3&#xff1a; 解题思路 题目理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#…

2024年AI绘画与写作工具排行榜:提升创作效率必备利器推荐

2024年&#xff0c;AI绘画和写作工具迎来全新突破&#xff0c;从艺术创作到内容写作&#xff0c;越来越多的创作者开始依赖AI工具来提升效率、拓展创意。而随着市场上AI工具的增多&#xff0c;如何选择适合的工具变得尤为重要。今天为大家推荐一些提升创作效率的AI绘画和写作利…

沈阳乐晟睿浩科技有限公司抖音小店新篇章

在当今数字化时代&#xff0c;电商行业如雨后春笋般迅速崛起&#xff0c;其中抖音小店凭借其庞大的用户基础、精准的推荐算法和便捷的购物体验&#xff0c;成为了电商领域的新宠。在这场电商变革中&#xff0c;沈阳乐晟睿浩科技有限公司&#xff08;以下简称“乐晟睿浩”&#…

SQL语言基础

SQL(Struct Query Language)是结构化查询语言的简称&#xff0c;是一种在关系型数据库中定义和操纵数据的标准语言。 不要使用面向对象的思想学习SQL&#xff0c;因为它不是面向对象的语言目标 SQL语言简介(了解)从数据库数据检索数据(重点)子查询(重点)Oracle常用函数(掌握) …

VBox增强功能、VBoxLinuxAdditions安装、共享文件夹问题解决

VBox增强功能、VBoxLinuxAdditions安装、共享文件夹问题解决 文章目录 VBox增强功能、VBoxLinuxAdditions安装、共享文件夹问题解决1.VBoxLinuxAdditions.run&#xff1a;找不到命令解决方案 2.可以看到共享文件夹。但是不能看到里面的内容。解决方案 参考 共享文件夹设置&…

一、在cubemx下RTC配置调试实例测试

一、rtc的时钟有lse提供。 二、选择rtc唤醒与闹钟功能 内部参数介绍 闹钟配置 在配置时间时&#xff0c;注意将时间信息存储起来&#xff0c;防止复位后时间重新配置。 if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0)! 0x55AA)//判断标志位是否配置过&#xff0c;没有则进…

MySQL 复合索引测试

对MySQL复合索引结合具体示例&#xff0c;各条件下索引使用情况的运行结果及分析。 目录 复合索引示例 创建表 新增数据 查询数据 选项A SQL查询 explain分析 选项B SQL查询 explain分析 选项C SQL查询 explain分析 选项D SQL查询 explain分析 选项E SQL查询…

JavaFx -- chapter05(多用户服务器)

chapter05(线程池-多用户服务器) 教学与实践目的 学会服务器支持多用户并发访问的程序设计技术。 多用户服务器是指服务器能同时支持多个用户并发访问服务器所提供的服务资源&#xff0c;如聊天服务、文件传输等。 第二讲的TCPServer是单用户版本&#xff0c;每次只能和一个…

初体验鸿蒙 HarmonyOS NEXT开发

上个星期三就下载了鸿蒙 HarmonyOS NEXT&#xff0c;安装好了后测试了一下&#xff0c;感觉界面和功能设计与IntelliJ IDEA很像&#xff0c;对初学者非常友好&#xff0c;所见即所得。不知道什么原因&#xff0c;写了代码后测试起来很慢&#xff0c;简单测试后就没有再动。 今天…

《DIY项目之“一只眼狗链”》:视频方案

项目背景 《DIY项目之“一只眼狗链”》合集主要记录完成一个DIY项目的所有过程。该合集预计更新频率为2~3周一篇&#xff08;同样属于一边做一边记录发布&#xff0c;时间上主要涉及PCB绘板、零部件采购、样品制作、编程等&#xff0c;存在一定的不可控性&#xff09;。 当前项…

Date工具类详细汇总-Date日期相关方法

# 1024程序员节 | 征文 # 目录 简介 Date工具类单元测试 Date工具类 简介 本文章是个人总结实际工作中常用到的Date工具类&#xff0c;主要包含Java-jdk8以下版本的Date相关使用方法&#xff0c;可以方便的在工作中灵活的应用&#xff0c;在个人工作期间频繁使用这些时间的格…

WPF拖拽交互全攻略及实现自定义拖拽控件及数据交换技巧解析

目录 1. 基本概念2 . 实现拖拽功能概述需要要实现基本的拖放&#xff0c;完成以下任务&#xff1a;其他操作 示例3.1 设置拖拽源&#xff0c;拖拽开始3.2 设置拖拽效果DragDropEffects 3.3 设置放置目标&#xff0c;处理拖拽数据拖拽输入DragEnter事件DragOver事件拖拽离开Drag…

ubuntu 22.04网线连接无ip、网络设置无有线网界面(netplan修复)

目前遇到过树莓派和其他设备安装 ubuntu22.04&#xff0c; 使用有线网络一段时间&#xff08;可能有其他软件安装导致&#xff09;造成有线网络未启动无ip分配的问题。 1、动态分配 通过命令行启动dhcpclient实现 网络eth0存在异常&#xff0c;网口灯电源和信号灯均点亮&am…

开关灯问题(c语言)

样例&#xff1a;10 10 &#xff0c;输出&#xff1a;1&#xff0c;4&#xff0c;9 5 5 &#xff0c;输出&#xff1a;1&#xff0c;4 代码如下 #include<stdio.h> //引入bool值的概念 #include<stdbool.h> int main() {int n 0;//n为灯的数量int m 0;…

【Android14 ShellTransitions】(八)播放动画

书接上回&#xff0c;话说当WMCore部分走到了Transition.onTransactionReady&#xff0c;计算完参与动画的目标&#xff0c;构建出TransitionInfo后&#xff0c;接下来就把这个包含了动画参与者的TransitionInfo发给了WMShell&#xff0c;然后就该播放动画了&#xff0c;这部分…

git快速合并代码dev->master

需求&#xff1a; 日常开发都是在dev分支进行开发&#xff0c;但是dev代码开发测试完成后&#xff0c;需要将dev代码合到master主分支上 开始合并代码&#xff1a; 一、场景 一个代码仓库&#xff0c;包含两个分支&#xff0c;一个是master&#xff0c;另一个是dev&#xff1b…

gitblit 学习-hook功能

hook功能 hook是什么 git hooks是git提供的&#xff0c;在发生特定事件时&#xff0c;允许用户添加自定义代码&#xff08;或操作&#xff09;的方式。 就像Vue中组件的生命周期钩子&#xff0c;比如&#xff0c;你想在vue组件创建后输出一行log, 你可能会这么写 有什么用&a…

Android Input的流程和原理

Android Input事件机制 Android系统是由事件驱动的&#xff0c;而Input是最常见的事件之一&#xff0c;用户的点击、滑动、长按等操作&#xff0c;都属于Input事件驱动&#xff0c;其中的核心就是InputReader和InputDispatcher。InputReader和InputDispatcher是跑在system_serv…