windows编程 使用C++实现多线程类
有时候我们想在一个类中实现多线程,主线程在某些时刻获得数据,可以“通知”子线程去处理,然后把结果返回。下面的实例是主线程每隔2s产生10个随机数,将这10随机数传给多线程类,让它接收到数据后马上打印出来。
首先看类的定义:
- #pragma once
- #include <iostream>
- #include <atlbase.h> // 使用到了atl类
- #include <atlsync.h>
- #include <vector>
- using namespace std;
- class CMultiThreadTest
- {
- public:
- bool Init(); // 初始化类成员
- bool UnInit(); // 释放资源
- void NotifyDowork(const std::vector<int> &data);
- static DWORD CALLBACK TestThread(LPVOID); // 线程函数,必须是静态函数
- DWORD TestProc(); // 线程工作实现
- private:
- std::vector<int> m_data; // 同步数据
- ATL::CEvent m_NotifyEvent; // 通知事件
- HANDLE m_hThread; // 线程句柄
- };
类中使用到了ALT类,需要包含atlbase.h和altsync.h头文件。函数TestThread必须是静态函数,因为CreateThread只接受全局或者静态函数。
首先先看Init()和UnInit()函数的实现:
- bool CMultiThreadTest::Init()
- {
- // 创建事件
- BOOL bRet = m_NotifyEvent.Create(NULL, TRUE, FALSE, NULL);
- if (!bRet) {
- return false;
- }
- // 挂起的方式创建线程
- m_hThread = CreateThread(NULL, 0, &CMultiThreadTest::TestThread, this, CREATE_SUSPENDED, NULL);
- if (NULL == m_hThread) {
- return false;
- }
- // 唤醒线程
- ResumeThread(m_hThread);
- return true;
- }
- bool CMultiThreadTest::UnInit()
- {
- // 通知线程处理data的数据
- if (m_NotifyEvent != NULL) {
- m_NotifyEvent.Set();
- }
- if (m_hThread != NULL)
- {
- // 预留100ms让线程处理完数据,100ms是个估值
- WaitForSingleObject(m_hThread, 100);
- CloseHandle(m_hThread);
- m_hThread = NULL;
- }
- return true;
- }
ATL::CEvent的成员函数Create接收4个参数,第四个参数指定Event的名字(它是可以有名字的),以便在其他进程可以找到该事件,这里我们不需要使用,把它设置为NULL,其他参数很容易理解,不赘述。
Init()函数值得注意的是我们创建的线程是以挂起的方式创建,所以必须调用ResumeThread唤醒线程,否则线程一值处于沉睡状态,不执行线程函数。
UnInit()函数比较简单,主要通知线程执行收尾工作,并释放类的资源。
下面我们来看看剩下的函数的实现。
- DWORD CALLBACK CMultiThreadTest::TestThread(LPVOID lpParam)
- {
- if (lpParam == NULL) {
- return 0;
- }
- CMultiThreadTest *lpThis = reinterpret_cast<CMultiThreadTest *>(lpParam);
- return lpThis->TestProc();
- }
- DWORD CMultiThreadTest::TestProc()
- {
- while (true)
- {
- // 每5s监听一次,秒数直接影响程序的性能
- DWORD dwRet = WaitForSingleObject(m_NotifyEvent, 5000);
- // 进入循环5s没有事件发生,不做任何处理
- if (dwRet == WAIT_TIMEOUT) {
- continue;
- }
- // 打印数组
- for (unsigned int i = 0; i < m_data.size(); i++)
- {
- cout <<m_data[i] <<" ";
- }
- cout <<endl;
- // 重置事件
- m_NotifyEvent.Reset();
- }
- return 0;
- }
- void CMultiThreadTest::NotifyDowork(const std::vector<int> &data)
- {
- m_data = data;
- m_NotifyEvent.Set(); // 通知线程该做事情了!
- }
首先我们看TestThread函数,它是线程的“入口“,线程被唤醒后执行该函数。值得注意的是,我们在创建线程的时候把对象指针this作为参数传递给创建线程函数,系统在调用TestThread的时候会把this传递回来,这里使用弱类型转换reinterpret_cast将LPVOID转化为CMultiThreadTest类的指针,reinterpret_cast是一个危险的类型转换,一般只适用于指针和整数之间的转换。有兴趣的同学可以参考C++ Primer第4版18.2.1章节。
线程函数将参数lpParam转化为对象指针后,执行对象的成员函数TestProc(),TestProc()实现主要的逻辑。这里可能会有人疑问,为什么不直接在TestThread()函数实现主要逻辑呢?这样做有两个好处,一是能够将线程函数逻辑和业务逻辑分离,其二就是TestThread是个静态函数,类静态函数只能处理类的静态成员变量,而很多时候我们希望线程处理类的非静态成员变量。
最后NotifyDowork函数很简单,该函数给外部调用,它把外部传进来的data赋值给类的非静态成员变量m_data,并通知线程处理m_data数据,TestProc中WaitForSingleObject函数接收到事件后往下执行,把m_data打印出来。
下面我们看看main函数的实现:
- int _tmain(int argc, _TCHAR* argv[])
- {
- CMultiThreadTest multiThreadTest;
- // 初始化失败
- if (!multiThreadTest.Init()) {
- return 0;
- }
- srand(unsigned int(time(NULL)));
- std::vector<int> data;
- while (true)
- {
- data.clear();
- // 产生10个随机数
- for (int i = 0; i < 10; i++)
- data.push_back(rand() % 1000);
- // 通知多线程类执行工作
- multiThreadTest.NotifyDowork(data);
- Sleep(2000);
- }
- multiThreadTest.UnInit();
- return 0;
- }
这段代码就不用解释了,记得包含头文件windows.h、time.h和vector。
总结:
多线程类的使用场景是,当一个线程或得到数据后,希望其他线程能够处理这部分数。多线程类实现还是比较简单的,首先创建线程和线程事件,实现给外部调用的接口,外部通过接口设置事件,通知线程执行。
转载于:https://www.cnblogs.com/daochong/p/6908694.html
windows编程 使用C++实现多线程类相关推荐
- 艾伟:基于.NET平台的Windows编程实战(四)—— 数据库操作类的编写
本系列文章导航 基于.NET平台的Windows编程实战(一)--前言 基于.NET平台的Windows编程实战(二)-- 需求分析与数据库设计 基于.NET平台的Windows编程实战(四)-- 数 ...
- Windows Forms 实现安全的多线程详解
原文:http://www.cnblogs.com/smartsoft2005/archive/2005/09/11/234687.html 前言 在我们应用程序开发过程中,经常会遇到一些问题,需要使 ...
- linux线程并不真正并行,多核时代:并行程序设计探讨(3)——Windows和Linux对决(多进程多线程)...
并行程序设计探讨(3)--Windows和Linux对决(多进程多线程) 前面的博文经过分析总结,最后得出两种并行技术:多进程多线程.多机协作.对于多进程和多线程来说,最有代表性且最常见的的莫过于Wi ...
- 《实用VC编程之玩转控件》第1课:Windows编程简介
本文转载自: VC驿站 https://www.cctry.com/thread-297374-1-1.html 0.开发环境: 操作系统:Microsoft Windows 7 Ultimate S ...
- windows编程经典书籍
总结: 大致浏览书中模块代码--实践--寻找书中更细致的原理层面解答 技术这东西需要领悟,读书时,书本告诉你一些东西,然后你去用,才能真正掌握.更多的时候,学习是螺旋上升的过程,开始OVERVIEW ...
- Windows编程的几本经典著作
Windows 程序设计(第5版): Programming Windows (Fifth Edition) 作者:Charles Petzold 此书被认为是Windows编程最好的导论性读本.在1 ...
- windows编程书籍推荐
本文从3个维度列出了学习<windows程序设计>的经典书籍,自己留个底也希望能对大家有所帮助 C/C++语言基础类: <Visual C++技术内幕> <C++ Pri ...
- Python Qt GUI设计:QTimer计时器类、QThread多线程类和事件处理类(基础篇—8)
目录 1.QTimer计时器类 2.QThread多线程类 3.事件处理类 一般情况下,应用程序都是单线程运行的,但是对于GUI程序来说,单线程有时候满足不了需求.例如,如果需要执行一个特别耗时的操作 ...
- 使用c++进行Windows编程中各种操作文件的方法 【转】
https://www.zhaokeli.com/article/8232.html 使用c++进行Windows编程中各种操作文件的方法 [转] 来源:赵克立博客 分类: C/C++ 标签:--发布 ...
最新文章
- json对象和json字符串转换方法
- Web安全学习笔记——SQL注入
- python装饰器类-python装饰器2:类装饰器
- Deepin 下安装 LAMP
- 小米MIX Alpha环绕屏手机还是跳票了,上市时间成迷,小米回应...
- 【算法】剑指 Offer 59 - I. 滑动窗口的最大值
- signature=73d4f2b7e55a02359b7d1bf362a074d6,SHOCK ABSORBER
- TCP三次握手四次挥手介绍
- 新建test.c为什么没有.h文件_新建STM32工程全局声明两个宏的原因
- win7 计算机定时关机脚本,w7系统定时关机命令如何设置_w7电脑怎样设置定时关机...
- 集成电路制造工艺及设备
- Windows下安装pip
- 替代NXP的CLRC663国产芯片来了,再也不用被老外卡脖子了
- 学生宿舍管理系统需求分析
- 大学计算机思维导论第七讲答案,中国大学MOOC计算思维导论网课答案
- win10下硬盘安装(更新)win10
- Fiddler之自动修改数据包(Free HTTP插件)
- 领导力21法则-- 要点总结
- 蓝桥杯基础练习python
- JavaSE基础阶段学习笔记
热门文章
- BZOJ1877:[SDOI2009]晨跑——题解
- PATH变量,cp,mv,cat,more,less,head,tail命令举例
- 逆向project实战--Afkayas.1
- Servlet具体解释
- pacific-atlantic-water-flow(不错)
- Android中监听ScrollView滑动停止和滑动到底部
- EasyUI-dialog
- sencha touch 彩色图标按钮(button+ico)
- 初识exe程序反汇编小感
- [参考]查看ORACLE DB信息的一些SQL