当前位置: 首页 > news >正文

两个线程同步执行:解决乱箭穿心(STL/Windows/Linux)

C++自学精简教程 目录(必读)

C++并发编程入门 目录

多线程同步

线程之间同步是指线程等待其他线程执行完某个动作之后再执行(本文情况)。

线程同步还可以是像十字路口的红绿灯一样,只允许一个方向的车同行,其他方向的车等待。

本文将使用信号量来实现线程同步。

一个线程通知另一个线程,另一个线程等待被通知信号。

一个发送线程先往控制台上打印1,这时候接收线程并不往控制台打印2,而是等待发送线程发给自己的信号,等到信号之后再打印2.

每次发送线程打印完自己的数据之后,睡眠1毫秒,给接收线程时间来完成自己的工作。

睡眠1毫秒合理吗?

这里睡眠1毫秒是合理的。

多个线程在协调工作的时候,每个线程都会需要时间来才能解决问题。

所以作为协调源头的线程1,应该给其他线程时间来处理问题,这是合理的。

例如,在音视频开发中,采集是源头,比如120HZ的视频,时间间隔是8.333ms,所有后续的编码线程,推流线程,等等,都需要在这有限的8.333毫秒之内完成自己的工作。

STL 写法

// condition_variable::notify_one
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <chrono>             //milliseconds
using namespace std;
using namespace chrono;std::mutex mutex1;
std::condition_variable event;void thread_sender_fun(void)
{while (true){cout << "1";event.notify_one();this_thread::sleep_for(milliseconds(1));}
}void thread_receiver_fun()
{while (true){std::unique_lock<std::mutex> lock(mutex1);event.wait(lock);cout << "2";}
}int main()
{std::thread thread_sender(thread_sender_fun);std::thread thread_receiver(thread_receiver_fun);// join them back:thread_sender.join();thread_receiver.join();return 0;
}

Windows 写法

#include <windows.h>
#include <iostream>
using namespace std;HANDLE event;//事件对象DWORD WINAPI sender_event_thread_fun(LPVOID lpParam)
{while (true){cout << "1";//干活SetEvent(event);//发出写完成信号,通知另一个线程该打印2了Sleep(1);}return 0;
}DWORD WINAPI receive_event_thread_fun(LPVOID lpParam)
{UNREFERENCED_PARAMETER(lpParam);while (true){DWORD dwWaitResult = WaitForSingleObject(event, INFINITE);// 等待信号,无限等待cout << "2";//干活}return 0;
}int main(void)
{event = CreateEvent(NULL,//是否需要人工ResetEvent重置为无信号状态://是:当该事件为有信号状态时,所有等待该信号的线程都变为可调度线程。//      并且,需要手动调用ResetEvent为无信号状态;//否:当该事件为有信号状态时,只有一个线程变为可调度线程。//      并且,系统自动调用ResetEvent将该对象设置为无信号状态。(一次性的信号)FALSE,FALSE,//初始状态:无信号状态TEXT("WriteFinishedEvent")// 事件对象名称);//创建线程HANDLE thread_sender  = CreateThread(NULL, 0, sender_event_thread_fun, NULL, 0, NULL);HANDLE thread_receive = CreateThread(NULL, 0, receive_event_thread_fun, NULL, 0, NULL);HANDLE handleArr[] = { thread_sender , thread_receive };//等待线程执行结束WaitForMultipleObjects(2, handleArr, TRUE, INFINITE);//释放资源CloseHandle(thread_sender);CloseHandle(thread_receive);CloseHandle(event);return 0;
}

不再乱箭穿心,总是先打印1,后打印2

Linux 写法

#include <pthread.h>
#include <semaphore.h>
#include <iostream>
#include <unistd.h>//usleep
using namespace std;sem_t event;void* thread_sender_fun(void* arg)
{while (true){cout << "1";sem_post(&event);usleep(1000);//休眠一毫秒}return 0;
}void* thread_receive_fun(void* arg)
{while (true){sem_wait(&event);cout << "2";}return 0;
}int main(int argc, char *argv[])
{pthread_t thread_sender;pthread_t thread_receiver;sem_init(&event, 0, 0);pthread_create(&thread_sender, NULL, thread_sender_fun, NULL);pthread_create(&thread_receiver, NULL, thread_receive_fun, NULL);pthread_join(thread_sender, NULL);pthread_join(thread_receiver, NULL);return 0;
}

不再乱箭穿心,总是先打印1,后打印2

相关文章:

两个线程同步执行:解决乱箭穿心(STL/Windows/Linux)

C自学精简教程 目录(必读) C并发编程入门 目录 多线程同步 线程之间同步是指线程等待其他线程执行完某个动作之后再执行&#xff08;本文情况&#xff09;。 线程同步还可以是像十字路口的红绿灯一样&#xff0c;只允许一个方向的车同行&#xff0c;其他方向的车等待。 本…...

Ubuntu18.04更改镜像源(网易,阿里,清华,中科大,浙大)

一&#xff0c;备份原来的源&#xff08;选做&#xff09; sudo cp /etc/apt/sources.list /etc/apt/sources_init.list 二&#xff0c;更换源 sudo gedit /etc/apt/sources.list 删除原来内容改为新的镜像源 1&#xff0c;清华源 deb https://mirrors.tuna.tsinghua.edu…...

字节码和机器码的区别

字节码和机器码是计算机程序在不同阶段的表示形式&#xff0c;它们的主要区别如下&#xff1a; 抽象级别不同&#xff1a;字节码是一种中间表示形式&#xff0c;位于源代码和机器码之间。它是一种与特定平台无关的低级表示形式&#xff0c;通常由编译器将源代码转换而来。而机器…...

go学习part21 Redis和Go(2)

1.三方库安装 309_尚硅谷_Go连接到Redis_哔哩哔哩_bilibili 借鉴&#xff1a; Golang 安装 Redis_go fiber 安装redis_柒柒伍贰玖。的博客-CSDN博客 三方redis库已经迁移到以下网址&#xff0c;go get github.com/gomodule/redigo/redis gomodule/redigo: Go client for Red…...

从0到1学会Git(第二部分):Git的本地操作和管理

写在前面:本文介绍了在本地仓库进行文件的处理以及本地的合并等操作。 前置知识:文件可以处在三个区域&#xff0c;分别为工作区&#xff0c;暂存区和本地仓库&#xff0c;我们此文的目标即是将文件存储在本地仓库中。我们可以将文件的区域理解为&#xff0c;cpu中&#xff0c…...

hive lateral view 实践记录(Array和Map数据类型)

目录 一、Array 1.建表并插入数据 2.lateral view explode 二、Map 1、建表并插入数据 2、lateral view explode() 3、查询数据 一、Array 1.建表并插入数据 正确插入数据&#xff1a; create table tmp.test_lateral_view_movie_230829(movie string,category array&…...

理解 std::thread::join

C多线程并发编程入门&#xff08;目录&#xff09; 本文用最简单易懂的实际案例&#xff0c;讲清楚了 join 的实际内涵&#xff0c;保证你过目不忘。 Hello join 示例 join 函数是我们接触C多线程 thread 遇到的第一个函数。 比如&#xff1a; int main() {thread t(f);t.…...

C#循环定时上传数据,失败重传解决方案,数据库标识

有些时候我们需要定时的上传一些数据库的数据&#xff0c;在数据不完整的情况下可能上传失败&#xff0c;上传失败后我们需要定时在重新上传失败的数据&#xff0c;该怎么合理的制定解决方案呢&#xff1f;下面一起看一下&#xff1a; 当然本篇文章只是提供一个思路&#xff0…...

R语言图形的组合( par(),layout(),par(fig()) )

引入d.class进行画图 > d.class<-read.csv("D://class.csv",header T) > attach(d.class) > opar<-par(no.readonly TRUE)非常简单的数据&#xff0c;需要可自取 链接&#xff1a;https://pan.baidu.com/s/1zNx5z9JsaaRqFueRgGY3mQ 提取码&#x…...

如何为 Flutter 应用程序创建环境变量

我们为什么需要环境变量&#xff1f; 主要用于存储高级机密数据&#xff0c;如果泄露可能会危及您产品的安全性。这些变量本地存储在每个用户的本地系统中&#xff0c;不应该签入存储库。每个用户都有这些变量的副本。 配置 在根项目中创建一个名为 .env 的文件夹&#xff08…...

「C++程序设计 (面向对象进阶)」学习笔记・一

0、引言 本专栏的系列文章是在学习 北京邮电大学 崔毅东 老师的《C程序设计 (面向对象进阶)》课程过程中整理的。欢迎前往专栏了解更多相关内容~ &#x1f600; 有关于现代 C 的基本介绍&#xff0c;请前往《现代C基本介绍》&#xff01; &#x1f514; 先决条件 本专栏的系列…...

Leetcode125. 验证回文串

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&…...

【Yellowbrick】特征可视化分析

Yellowbrick特征可视化分析 ⭐Yellowbrick⭐特征分析可视化⭐Rank1D⭐Rank2D ⭐Yellowbrick Yellowbrick是一个用于可视化机器学习模型和评估性能的Python库。它提供了一系列高级可视化工具&#xff0c;帮助数据科学家和机器学习从业者更好地理解、调试和优化他们的模型。 它在…...

Android大厂需要刷的(999道)面试题

想必大家都在为今年的金九银十做准备&#xff0c;今年也是最为艰难的一年。作为程序员从未感觉到如此艰难&#xff0c;身边不是被辞退就是找不到工作。先不说2023年应届生毕业即失业&#xff0c;作为开发15年的老Android程序员&#xff0c;现在也在和300个人挣一个岗位。 肉少…...

Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法

不论搭建什么工程&#xff0c;运行什么文件&#xff0c;只要在Pycharm中出现ImportError: DLL load failed: 找不到指定的模块这样的问题&#xff0c;以下方法都适用&#xff01;&#xff01;&#xff01; 一、问题描述 我在使用pycharm连接webots&#xff0c;用python控制机…...

Java设计模式:四、行为型模式-08:策略模式

文章目录 一、定义&#xff1a;策略模式二、模拟场景&#xff1a;策略模式三、违背方案&#xff1a;策略模式3.0 引入依赖3.1 工程结构3.2 优惠券折扣计算类3.3 单元测试 四、改善代码&#xff1a;策略模式4.1 工程结构4.2 策略模式结构图4.3 优惠券折扣实现4.3.1 定义优惠券接…...

ICCOA蓝牙数字车钥匙2.0

近期&#xff0c;ICCOA智慧车联开放联盟宣布&#xff0c;由小米、vivo、OPPO、长安、深蓝、吉利、极氪、比亚迪、北汽、蔚来、零跑、雪球、瓶钵、融卡等企业联合参与制定的ICCOA蓝牙数字车钥匙2.0标准&#xff08;简称DK2.0&#xff09;&#xff0c;于2023年9月1日正式发布实施…...

ArcGIS土地利用程度综合指数分析

成图展示&#xff1a; 土地利用程度综合指数 第一步 准备数据 使用的数据为2010年河南省土地利用类型数据与其行政区划县级数据&#xff08;为了节省操作&#xff0c;这里使用上次实验的部分数据[1]&#xff0c;各土地利用类型已被提取&#xff09; 第二步 面积统计 水域为例…...

服务端请求伪造(SSRF)及漏洞复现

文章目录 渗透测试漏洞原理服务端请求伪造1. SSRF 概述1.1 SSRF 场景1.1.1 PHP 实现 1.2 SSRF 原理1.3 SSRF 危害 2. SSRF 攻防2.1 SSRF 利用2.1.1 文件访问2.1.2 端口扫描2.1.3 读取本地文件2.1.4 内网应用指纹识别2.1.5 攻击内网Web应用 2.2 SSRF 经典案例2.2.1 访问页面2.2.…...

v-model和v-bind

v-model&#xff0c;它其实就是一个语法糖&#xff0c;作用就是双向绑定表单控件&#xff08;radio, text,address,email,select,checkbox,textarea&#xff09; v-bind(简写形式:value值),用于绑定属性值&#xff0c;只能实现数据的单项绑定。 <template> <div>…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...