[编程基础] 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 连接和 ...
随机推荐
- 生产系统CPU飙高问题排查
现状 生产系统CPU占用过高,并且进行了报警 排查方法 执行top命令,查看是那个进程导致的,可以确定是pid为22168的java应用导致的 执行top -Hp命令,查看这个进程的那个线程导致cpu ...
- 齐博x1第四季《模块插件的制作》系列21-公共表单器的参数选项(7)
password 密码类型 和text一样,只不过type类型是password,密码类型输入时,显示星号.即Html中的密码框类型 icon 字体图标类型 和列表页一样,把css的字体图标引入到了表 ...
- 30.Serializers模块源码解析
rest_framework序列化类的继承关系 field类: 序列化基类的基类 BaseSerializer: 继承field 派生ListSerializer序列化类 Serializer: 继承 ...
- UVA10763
菜鸡退役人来水黄了-- \(\sf{Solution}\) 搞不懂为什么要排序,这不是两个数组直接模拟的数数题吗. 读入后,对于每个学生,令他要去的学校以及他现在所在学校人数对应加一,再 check ...
- k8s机器群扩容问题
今天遇到了一个很奇葩的问题.公司新人吧k8s集权扩容完后,发现服务器上的磁盘没有做分区2T磁盘没有做任何动作 把两台slave节点扩容上去的节点弄到了/目录.由于是生产环境情况比较特殊并没通过kube ...
- iptables和firewalld基础
1.四表五链概念: filter表 过滤数据包 Nat表 用于网络地址转换(IP.端口) Mangle表 修改数据包的服务类型.TTL.并且可以配置路由实现QOS Raw表 决定数据包是否被状态跟踪机 ...
- QML 怎么调用 C++ 中的内容?
以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/z_JlmNe6cYldNf11Oad_JQ 先说明一下测试环境 编 ...
- 嵌入式-Linux基础操作
Crtl+Alt+T:调出命令窗口 xrandr:列出分辨率列表 设置窗口的分辨率大小为1280x960:xrandr -s 1280x960 通过命令窗口来执行一段C语言程序: VI工具的使用: ( ...
- [排序算法] 简单选择排序 (C++)
简单选择排序原理 简单选择排序 SelectSort 是一种十分直观地排序方法.其原理是每次从未排序的元素中找到当前最小的元素,放在当前未排序序列的首位.一直重复操作直至最后未排序的元素个数为 0,即 ...
- 本地JS文件批量压缩
最近在维护一个小后台项目,有段JS需要压缩上传到CDN存储服务器.由于之前压缩的JS文件都比较少,都是手动压缩的.这次需要压缩的文件比较多,所以用了批量压缩.特此记录一下,方便大家和自己以后再用到的时 ...