原始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-事件处理的需求的更多相关文章

  1. [编程基础] C++多线程入门4-数据共享和资源竞争

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++ 11标准. 4 数据共享和资源 ...

  2. [编程基础] C++多线程入门7-条件变量介绍

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 7 条件变 ...

  3. [编程基础] C++多线程入门5-使用互斥锁解决资源竞争

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 5 使用互 ...

  4. [编程基础] C++多线程入门8-从线程返回值

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 8 从线程返回值 8 ...

  5. [编程基础] C++多线程入门1-创建线程的三种不同方式

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 1 创建线程的三种不 ...

  6. [编程基础] C++多线程入门10-packaged_task示例

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 10 pa ...

  7. [编程基础] C++多线程入门9-async教程和示例

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 9 asy ...

  8. [编程基础] C++多线程入门3-小心地将参数传递给线程

    原始C++标准仅支持单线程编程.新的C++标准(称为c++11或c++0x)于2011年发布.在c++11中,引入了新的线程库.因此运行本文程序需要C++至少符合c++11标准. 文章目录 3 小心地 ...

  9. [编程基础] C++多线程入门2-连接和分离线程

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 2 连接和 ...

随机推荐

  1. CVPR2022 Oral OGM-GE阅读笔记

    标题:Balanced Multimodal Learning via On-the-fly Gradient Modulation(CVPR 2022 Oral) 论文:https://arxiv. ...

  2. Java8新特性之Stream流(含具体案例)

    一.概述   Stream 流是 Java 8 新提供给开发者的一组操作集合的 API,将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选.排序.聚合等.元素 ...

  3. 如何在IDEA中自定义模板、快速生成完整的代码?

    文章目录 1.修改现有的模板 2.自定义模板 3.在代码中测试自定义模板 1.修改现有的模板 打开设置面板- settings 2.自定义模板 选择定义模板组 选择创建模板 define 代表应用的范 ...

  4. 说说 Redis pipeline

    更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号 Max的学习札记. Redis 客户端和服务端之间是采用 TCP 协议进行通信的,是基于 Request/Respon ...

  5. 用昇腾AI护航“井下安全”

    摘要:基于CANN(异构计算架构)打造的"智能矿山安全生产管理平台",能够更便捷和更高效地服务于更多矿山安全生产建设. 本文分享自华为云社区<华为携手云话科技助力矿山智能化, ...

  6. 题解 CF327A Flipping Game

    前言 数据水的一批,\(\mathcal{O}(n^3)\) 给过我觉得是不应该的. 题意 有一个由 \(0\) 和 \(1\) 组成的序列 \(a_1,a_2,a_3,a_4....,a_n\) . ...

  7. 如何使用ffmpeg缩小视频的大小?

    如何使用ffmpeg缩小视频的大小? 看到这个答案.为方便起见,在下面引用: 通过将1 GB除以以秒为单位的视频长度来计算所需的比特率.因此,对于长度为16:40(1000秒)的视频,请使用10000 ...

  8. 利用xtrabackup8完全,增量备份及还原MySQL8

    利用xtrabackup8完全,增量备份及还原MySQL8 1.环境准备 服务器 作用 数据库版本 xtrabackup版本 10.0.0.8 数据备份 mysql8.0.26 8.0.28 10.0 ...

  9. 【单元测试】Junit 4(四)--Junit4参数化

    1.0 前言 ​ JUnit 4引入了一项名为参数化测试的新功能.参数化测试允许开发人员使用不同的值反复运行相同的测试. 1.1 参数化设置 这里我们直接上例子吧. 题目: ​ 输入小写的字符串.如字 ...

  10. ABAP 调用HTTP上传附件

    1.需求说明 在SAP中调用第三方文件服务器的HTTP请求,将文件保存在文件服务器上,并返回保存的文件地址.SAP保存返回的文件地址,通过浏览器进行访问. 2.需求实现 2.1.POSTMAN测试 通 ...