[编程基础] C++多线程入门6-事件处理的需求
原始C++标准仅支持单线程编程。新的C++标准(称为C++11或C++0x)于2011年发布。在C++11中,引入了新的线程库。因此运行本文程序需要C++至少符合C++11标准。
6 事件处理的需求
6.1 使用说明
在本文中,我们将讨论多线程中事件处理的需求。有时,线程需要等待事件发生,例如条件变为真或任务由另一个线程完成。假设我们正在构建一个基于网络的应用程序。该应用程序执行以下任务,
- 与服务器进行一些连接
- 从XML文件加载数据
- 对从XML加载的数据进行处理
如我们所见,任务1不依赖于任何其他任务,但是任务3依赖于任务2。因此,这意味着任务1和任务2可以由不同的线程并行运行以提高应用程序的性能。因此,让我们将其分解为一个多线程应用程序,现在,它包括两个线程。
线程1的职责是:
- 与服务器进行一些连接
- 等待线程2从XML加载数据
- 对从XML加载的数据进行处理
线程2的职责是
- 从XML加载数据
- 通知另一个线程,即等待消息
如上图所示,线程1执行一些操作,然后等待事件/条件发生。这里的事件或条件是数据是否成功加载。线程1收到该事件后,便会对数据执行一些处理。当线程1忙于执行“握手机制”时,线程2并行加载数据。当线程2成功地从XML加载数据时,它随后通过发信号通知该事件来通知线程1。现在,当发出事件或条件信号时,线程1将继续处理数据。
使它成为多线程有什么好处?当线程1忙于某种握手机制时,线程2将从XML并行加载数据。因此,它将提高应用程序的性能,现在,如何实现这一目标两个选项。
选项1
将布尔全局变量设为默认值false。在线程2中将其值设置为true,线程1将继续在循环中检查其值,并且一旦变为true,线程1将继续处理数据。但是由于它是两个线程共享的全局变量,因此需要与互斥锁同步。让我们看看它的代码。
#include<iostream>
#include<thread>
#include<mutex>
class Application
{
std::mutex m_mutex;
bool m_bDataLoaded;
public:
Application()
{
m_bDataLoaded = false;
}
void loadData()
{
// Make This Thread sleep for 1 Second
// 线程等待一秒
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "Loading Data from XML" << std::endl;
// Lock The Data structure
// 互斥锁
std::lock_guard<std::mutex> guard(m_mutex);
// Set the flag to true, means data is loaded
// 表示数据被加载
m_bDataLoaded = true;
}
void mainTask()
{
std::cout << "Do Some Handshaking" << std::endl;
// Acquire the Lock
// 获得锁
m_mutex.lock();
// Check if flag is set to true or not
// 检查数据是否被加载
while (m_bDataLoaded != true)
{
// Release the lock
// 释放锁
m_mutex.unlock();
//sleep for 100 milli seconds
// 等待100毫秒
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Acquire the lock
// 获得锁
m_mutex.lock();
}
// Release the lock
// 释放锁
m_mutex.unlock();
// Doc processing on loaded Data
// 加载数据的文档处理
std::cout << "Do Processing On loaded Data" << std::endl;
}
};
int main()
{
Application app;
std::thread thread_1(&Application::mainTask, &app);
std::thread thread_2(&Application::loadData, &app);
thread_2.join();
thread_1.join();
return 0;
}
输出为:
Do Some Handshaking
Loading Data from XML
Do Processing On loaded Data
这种方式具有以下缺点:
线程将继续获取该锁并释放它只是为了检查该值,因此它将消耗CPU周期,并使线程1变慢,因为它需要获取相同的锁来更新bool标志。因此,显然,我们需要一种更好的机制来实现这一目标,例如,如果某种程度上线程1可以通过等待某个事件被发出信号而阻塞,而另一个线程可以通过该信号发出该事件并使线程1继续运行,则该机制就可以实现。这样可以节省许多CPU周期并提供更好的性能。但是问题是如何实现这一目标?我们将在选项2中看到答案。
选项2
我们可以使用条件变量来实现。条件变量是一种事件,用于在2个线程之间发信号。一个线程可以等待它发出信号,而另一个线程可以发出信号。下一篇文章将讲述条件变量的详细说明以及使用条件变量解决此问题的方法。
6.2 参考
https://thispointer.com//c11-multithreading-part-6-need-of-event-handling/
[编程基础] C++多线程入门6-事件处理的需求的更多相关文章
- [编程基础] C++多线程入门4-数据共享和资源竞争
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++ 11标准. 4 数据共享和资源 ...
- [编程基础] C++多线程入门7-条件变量介绍
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 7 条件变 ...
- [编程基础] C++多线程入门5-使用互斥锁解决资源竞争
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 5 使用互 ...
- [编程基础] C++多线程入门8-从线程返回值
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 8 从线程返回值 8 ...
- [编程基础] C++多线程入门1-创建线程的三种不同方式
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 1 创建线程的三种不 ...
- [编程基础] C++多线程入门10-packaged_task示例
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 10 pa ...
- [编程基础] C++多线程入门9-async教程和示例
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 9 asy ...
- [编程基础] C++多线程入门3-小心地将参数传递给线程
原始C++标准仅支持单线程编程.新的C++标准(称为c++11或c++0x)于2011年发布.在c++11中,引入了新的线程库.因此运行本文程序需要C++至少符合c++11标准. 文章目录 3 小心地 ...
- [编程基础] C++多线程入门2-连接和分离线程
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 2 连接和 ...
随机推荐
- 齐博X1数据表之系统参数
https://v.youku.com/v_show/id_XMzg0MTEzMzEyOA== 不会插入视频 直接发 优酷地址吧= =!
- 如何规范App广告的隐私获取,让用户拥有更多知情权?
随着互联网的不断普及,越来越多老百姓使用智能设备触达互联网.但用户经常发现自己无意间提到的东西,打开App就收到相关产品的广告推送,甚至有人怀疑手机App是通过麦克风来窃取自己平时聊天信息中的关键词进 ...
- python基础爬虫,翻译爬虫,小说爬虫
基础爬虫: # -*- coding: utf-8 -*- import requests url = 'https://www.baidu.com' # 注释1 headers = { # 注释2 ...
- 【一】ERNIE:飞桨开源开发套件,入门学习,看看行业顶尖持续学习语义理解框架,如何取得世界多个实战的SOTA效果?
参考文章: 深度剖析知识增强语义表示模型--ERNIE_财神Childe的博客-CSDN博客_ernie模型 ERNIE_ERNIE开源开发套件_飞桨 https://github.com/Pad ...
- Linux三剑客awk
Linux三剑客awk awk是一个强大的linux命令,有强大的文本格式化的能力,好比将一些文本数据格式化成专业的excel表的样式 awk早期在Unix上实现,我们用的awk是gawk,是GUN ...
- SpringBoot简单快速入门操作
项目类分为: dao层 server层 controller层 Mapper → Server→ controller mapper层(必须要用interface创建) 创建后,首先要在方法前加@Ma ...
- 【第5篇】AI语音简介
1.3 AI语音简介 AI语音既人工智能语音技术,以语音识别技术为开端,实现人机语言的通信,包括语音识别技术(ASR).自然语言处理技术(NLP)和语音合成技术(TTS).通俗点说就是通过语音这个媒 ...
- VBA工程设置密码
VBA 工程设置密码 Alt + F11,进入程序界面: 工具---> VBAProject属性---> 保护---> 查看时锁定工程前打勾,并在下面的密码区输入密码.
- MvvmLight框架的基本使用
关于MvvmLight框架的介绍可以看这篇,说的很详细,在此记录下来以作复习,通过一个简单的例子说明MvvmLight的基本使用 https://www.cnblogs.com/3xiaolonglo ...
- 【CVE-2022-0543】Redis Lua沙盒绕过命令执行复现
免责声明: 本文章仅供学习和研究使用,严禁使用该文章内容对互联网其他应用进行非法操作,若将其用于非法目的,所造成的后果由您自行承担,产生的一切风险与本文作者无关,如继续阅读该文章即表明您默认遵守该内容 ...