两个线程同步执行:解决乱箭穿心(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

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

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

相关文章

C#,《小白学程序》第八课:列表(List)应用之二“编制高铁列车时刻表”

1 文本格式 /// <summary> /// 车站信息类 class /// </summary> public class Station { /// <summary> /// 编号 /// </summary> public int Id { get; set; } 0; /// <summary> /// 车站名 /// </summary&g…

JavaScript设计模式(四)——策略模式、代理模式、观察者模式

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Python3 条件控制

Python3 条件控制 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 代码执行过程&#xff1a; if 语句 Python中if语句的一般形式如下所示&#xff1a; if conditi…

Spring Cloud Foundry上使用通配符模式匹配进行的安全绕过漏洞 CVE-2023-20873

文章目录 0.前言1.参考文档2.基础介绍描述如果满足以下任一条件&#xff0c;应用程序就不会有太大风险&#xff1a;受影响的Spring产品和版本 3.解决方案3.1. 升级版本3.2. 替代方案 0.前言 背景&#xff1a;公司项目扫描到 Spring Cloud Foundry上使用通配符模式匹配进行的安全…

将符号分隔的文本文件txt转换为excel的实现

文本文件如下&#xff1a; 现在不好处理&#xff0c;打算将其转换为excel&#xff0c;其中通过冒号分割&#xff1a;line.split(":") main方法如下&#xff1a; public static void main(String[] args) {String textFilePath "D:\\zoom\\期刊\\J_Medline\\J_…

肖sir__linux详解__001

linux详解: 1、ifconfig 查看ip地址 2、6版本&#xff1a;防火墙的命令&#xff1a; service iptables status 查看防火墙状态 service iptables statrt 开启防火墙 service iptables stop 关闭防火墙 service iptables restart 重启防火墙状态 7版本&#xff1a; systemctl s…

【Golang】函数篇

1、golang函数基本定义与使用 func 函数名 (形参列表) (返回值类型列表) {函数体return 返回值列表 }其中func用于表明这是一个函数&#xff0c;剩下的东西与其他语言的函数基本一致&#xff0c;在定义与使用的时候注意函数名、参数、返回值书写的位置即可。下面使用一个例子…

【超详细~KVM】KVM概述、安装及简单操作-------从小白到大神之路之学习运维第91天

第四阶段提升 时 间&#xff1a;2023年8月30日 参加人&#xff1a;全班人员 内 容&#xff1a; KVM概述、安装及简单操作 目录 一、KVM 概述 二、KVM工作原理 三、KVM应用场景 四、centos7 下安装部署 五、新建虚拟机步骤 1、创建存储池并创建存储卷 2、点击号创建…

Java【手撕滑动窗口】LeetCode 438. “字符串中所有异位词“, 图文详解思路分析 + 代码

文章目录 前言一、字符串中所有异位词1, 题目2, 思路分析2.1, 引入哈希表找出异位词2.2, 引入变量记录"有效字符的个数"2.3, left 右移维护窗口2.4, 总结核心步骤 3, 代码 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; Ja…

【QT】使用qml的QtWebEngine遇到的一些问题总结

在使用qt官方的一些QML的QtWebEngine相关的例程的时候&#xff0c;有时在运行会报如下错误&#xff1a; WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed 这个问题在main函数里面最前面加上&#xff1a; QCoreApplication::setAttr…

C++:初识类与this指针

文章目录 前言一、类类的定义和实例化类的访问限定符类的作用域计算类的大小 二、类的成员函数的this指针总结 个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》 前言 一、类 类的定义和实例化 注意类定义结束时后面分号( ; )不能省略。 类…

Apolo学习

安装&#xff08;java1.8 mysql 5.6.5以上&#xff09; 下载quickStart的包&#xff0c;早apollo下执行两个sql。如果不执行这两个sql&#xff0c;apollo是执行不起来的。会有两个表来记录apollo的执行情况。其中一个表叫apolloportaldb 在apollo目录下会有执行的包。.sh是…

嵌入式学习之进程

1.进程间通信概述 UNIX系统IPC是各种进程通信方式的统称。 2.管道通信原理 特点&#xff1a; 1.它是半双工的&#xff08;即数据只能在一个方向上流动&#xff09;&#xff0c;具有固定的读端和写端。 2.它只能用于具有亲缘关系的进程之间通信&#xff08;也是父子进程或者…

java设计模式---策略模式

策略模式的定义 策略设计模式是一种行为设计模式。当在处理一个业务时&#xff0c;有多种处理方式&#xff0c;并且需要再运行时决定使哪一种具体实现时&#xff0c;就会使用策略模式。 策略模式的类图&#xff1a; 策略模式的实现 在支付业务中&#xff0c;有三种付款方式&…

Kubernetes(k8s)上安装Prometheus和Grafana监控

Kubernetes上安装Prometheus和Grafana监控 环境准备Kubernetes准备 安装项目开始安装下载安装的项目安装项目替换镜像替换kube-state-metrics替换prometheus-adapter 修改Service修改alertmanager-service.yaml修改grafana-service.yaml修改prometheus-service.yaml 执行这些ya…

虚拟世界指南:从零开始,一步步教你安装、配置和使用VMware,镜像ISO文件!

本章目录 CentOS简介镜像下载一、新建虚拟机&#xff08;自定义&#xff09;1、进入主页&#xff0c;在主页中点击“创建新的虚拟机”2、点击创建虚拟机创建自己的虚拟机。可以选择自定义3、在“硬件兼容性(H)中选择&#xff1a;Workststion 15.x” ->下一步4、选择“稍后安…

Langchain使用介绍之outparser 和memory

上一篇博客中对Langchain中prompt进行了详细的介绍&#xff0c;此篇博客将介绍Langchain中的outparser和memory。当调用大模型生成内容时&#xff0c;返回的内容默认是string类型&#xff0c;这对于我们获取response中的某些内容信息可能会带来障碍&#xff0c;例如返回的内容本…

HP惠普星15青春版/惠普小欧笔记本电脑15s-du1008tx原装出厂Win11系统

适用型号&#xff1a;15s-du1007tx、15s-du1008tx、15s-du1009tx、15s-du1010tx、15s-du1011tx、15s-du1012tx、15s-du1013tx 自带所有驱动、出厂主题壁纸LOGO、Office办公软件、惠普电脑管家等预装程序 所需要工具&#xff1a;32G或以上的U盘 文件格式&#xff1a;ISO 文件大…

msvcr120.dll文件丢失的解决方法,四种快速解决发方法分享

你是否曾经在使用电脑时遭遇过 msvcr120.dll 文件丢失的困扰&#xff1f;如果你对此感到茫然无措&#xff0c;那么请跟随我的脚步&#xff0c;让我们一起探索这个问题的根源。当我一如既往地打开电脑&#xff0c;准备开始一天的工作时&#xff0c;突然发现许多应用程序无法正常…

android framework之Applicataion启动流程分析(三)

现在再回顾一下Application的启动流程&#xff0c;总的来说&#xff0c;虽然进程的发起是由ATMS服务发起的&#xff0c;但是进程的启动还是由AMS负责&#xff0c;所以需要调用AMS的startProcess()接口完成进程启动流程&#xff0c;AMS要处理的事情很多&#xff0c;它将事务交给…