简单的C++线程类实现, windows平台

一个抽象的线程基类, 再来个具体的线程类并实现相关接口,再写个主函数来调用下。上代码:

Thread.h

/*
Windows平台线程类实现
开发环境: Win7_x64 + VC2012
*/
#ifndef __THREAD_H__
#define __THREAD_H__
#pragma once
#include <string>
#include <windows.h>
/*
1. 线程基类, 要创建新的线程类, 只需要继承此类并实现相关接口
2. 要开启线程并运行只需要调用Start()函数
3. 未完善地方: 应该写个虚函数Stop(), 当线程过程在运行时可以设置下运行标志变量让线程
退出循环过程, 再作些清理工作, 避免暴力终止线程。
*/
class CThread								// 抽象的线程基类
{
public:
CThread(const std::string threadName = "noNamed");
virtual ~CThread();
virtual void Run() = 0;					// 线程执行过程
virtual bool Start(bool bSuspended/* = false*/);
void Join(int timeout = -1);			// 等待超时时间为负时, 表示无限等待
void Resume();							// 恢复挂起的线程
void Suspend();							// 挂起线程
bool Terminate(unsigned long exitCode);	// 结束线程
unsigned int GetThreadID();				// 获取线程ID
std::string GetThreadName();
void SetThreadName(std::string threadName);
private:
bool CreateThread(bool bSuspended = false);// 开始运行线程
static unsigned int WINAPI StaticThreadFunc(void* arg);	// 线程函数
protected:
HANDLE			m_handle;
std::string		m_threadName;
unsigned int	m_threadID;
volatile bool	m_bRun;					// 表明线程是否已成功创建(实际上与m_handle含义相同了)
};
#endif


Thread.cpp:

#include <iostream>
#include <process.h>
#include "Thread.h"
CThread::CThread(const std::string threadName)
: m_threadName(threadName), m_threadID(0), m_bRun(false)
{
}
CThread::~CThread()
{
printf("~CThread()\n");
}
bool CThread::Start(bool bSuspend/* = false*/)		// 创建线程并运行(默认)或挂起
{
m_bRun = CreateThread(bSuspend);
return m_bRun;
}
bool CThread::CreateThread(bool bSuspend/* = false*/)	// 创建线程并运行(默认)或挂起
{
if(!m_bRun)
{
if(bSuspend)
m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, CREATE_SUSPENDED, &m_threadID);
else
m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, 0, &m_threadID);
m_bRun = (NULL != m_handle);
}
return m_bRun;
}
void CThread::Join(int timeout/* = -1*/)			// 等待超时时间(毫秒)为负时, 表示无限等待
{
if(m_handle && m_bRun)
{
if(timeout < 0)
timeout = INFINITE;
::WaitForSingleObject(m_handle, timeout);
}
}
void CThread::Resume()								// 恢复挂起的线程
{
if(m_handle && m_bRun)
::ResumeThread(m_handle);
}
void CThread::Suspend()								// 挂起线程
{
if(m_handle && m_bRun)
::SuspendThread(m_handle);
}
bool CThread::Terminate(unsigned long exitCode)		// 结束线程
{
if(m_handle && m_bRun)
{
if(::TerminateThread(m_handle, exitCode))
{
::CloseHandle(m_handle);
m_handle = NULL;
m_bRun = false;
return true;
}
}
return false;
}
unsigned int CThread::GetThreadID()
{
return m_threadID;
}
std::string CThread::GetThreadName()
{
return m_threadName;
}
void CThread::SetThreadName(std::string threadName)
{
m_threadName = threadName;
}
unsigned int CThread::StaticThreadFunc(void* arg)		// 线程函数
{
CThread* pThread = (CThread*)arg;					// 取得线程类指针
pThread->Run();										// 执行线程过程函数
return 0;
}


Thread1.h

#ifndef __THREAD1_H__
#define __THREAD1_H__
#pragma once
#include "Thread.h"
/*
1. 要创建一个新线程类时只需要继承CThread, 然后在Run()中实现自己的线程过程(Run())
*/
class CThread1: public CThread				// 线程类1
{
public:
CThread1(const std::string threadName = "noNamed");
virtual ~CThread1(void);
bool Start(bool bSuspended/* = false*/);
virtual void Run();
};
#endif


Thread1.cpp

#include <iostream>
#include "Thread1.h"
CThread1::CThread1(const std::string threadName): CThread(threadName)
{
}
CThread1::~CThread1()
{
printf("~CThread1()\n");
}
bool CThread1::Start(bool bSuspended/* = false*/)
{
// todo: 此处可添加一些初始化代码
return CThread::Start(bSuspended);
}
void CThread1::Run()
{
int cnt = 0;
while(cnt <= 10)
{
std::cout << "Hello " << m_threadName << "::Run(): " << cnt++ << std::endl;
Sleep(200);
}
}


main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "Thread1.h"
#define N 15
int main(int argc, char* argv[])
{
char buf[20] = {0};
CThread* t[N] = {NULL};
for(int i = 0; i < N; i++)
{
sprintf(buf, "Thread%d", i+1);
t[i] = new CThread1(buf);
t[i]->Start(true);
std::cout << t[i]->GetThreadName() << ": " << t[i]->GetThreadID() << std::endl;
t[i]->Resume();
}
for(int i = 0; i < N; i++)
t[i]->Join();
return 0;
}


 

 

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

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

相关文章

yarn 包管理器设置淘宝镜像和sass镜像

淘宝镜像 yarn config set registry http://registry.npm.taobao.org/ -g sass镜像 yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g

奈奎斯特采样定理:

&#xff08;1&#xff09;奈奎斯特采样定理&#xff1a; 当采样频率fs.max大于信号中最高频率fmax的2倍时&#xff0c;即&#xff1a;fs.max>2fmax,则采样之后的数字信号完整地保留了原始信号中的信息&#xff1b; 转载于:https://www.cnblogs.com/jocobHerbertPage/archiv…

TCP重组数据包分析

参照TCP/IP详解第二卷24~29章&#xff0c;详细论述了TCP协议的实现&#xff0c;大概总结一下TCP如何向应用层保证数据包的正确性、可靠性&#xff0c;即TCP如何实现对数据报文的重组。 首先要设计两个报文队列&#xff0c;一个存放正常来到的报文&#xff0c;一个存放失序到来…

vue项目引入字体图标iconfont

直接将icon下载成图片使用或者通过import方式移入url使用&#xff0c;看此篇 本文介绍两种使用方案&#xff1a;1.使用Font class引入字体图标&#xff08;推荐&#xff09; 2.使用Symbol 引用 如果是分批次的下载了好几次字体图标&#xff0c;那么可以将解压的代码css等文件放…

Why is processing a sorted array faster than an unsorted array?

这是我在逛 Stack Overflow 时遇见的一个高分问题&#xff1a;Why is processing a sorted array faster than an unsorted array?&#xff0c;我觉得这是一个非常好的用来讲分支预测&#xff08;Branch Prediction&#xff09;的例子&#xff0c;分享给大家看看 一、问题引入…

IP分片和TCP分段的区别

1.MTU(Maximum Transmission Unit&#xff0c;MTU)&#xff0c;最大传输单元 &#xff08;1&#xff09;以太网和802.3对数据帧的长度都有一个限制&#xff0c;其最大值分别是1500和1492个字节。链路层的这个特性称作MTU。不同类型的网络大多数都有一个上限。如果IP层有一个数…

求素数: 一般线性筛法 + 快速线性筛法

From: http://blog.csdn.net/dinosoft/article/details/5829550 素数总是一个比较常涉及到的内容&#xff0c;掌握求素数的方法是一项基本功。 基本原则就是题目如果只需要判断少量数字是否为素数&#xff0c;直接枚举因子2 。。N^(0.5) &#xff0c;看看能否整除N。 如果需要…

uni-app微信小程序uni.getLocation获取位置;authorize scope.userLocation需要在app.json中声明permission;小程序用户拒绝授权后重新授权

需求&#xff1a;点击按钮获取当前微信位置&#xff0c;以及点击拒绝授权后&#xff0c;下次点击还可以拉起授权窗口&#xff1b; 拒绝授权后重新拉起授权操作&#xff1a; 直接授权操作&#xff1a; 一、问题1&#xff1a;报authorize scope.userLocation需要在app.json中声明…

安装了cnpm,还是报错cnpm : 无法加载文件 C:\Users\admin\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。

当我安装了cnpm 但是使用的时候还是报错&#xff1a; 解决方法&#xff1a; 1、以管理员身份打开Windos PowerShell 2、输入“ set-ExecutionPolicy RemoteSigned”回车 3、根据提示&#xff0c;输入A或Y&#xff0c;回车 4、再次执行cnpm -v&#xff0c;即可看到提示版本…

PHP代码审计之反序列化攻击链CVE-2019-6340漏洞研究

关键词 php 反序列化 cms Drupal CVE-2019-6340 DrupalKernel 前言 简简单单介绍下php的反序列化漏洞 php反序列化漏洞简单示例 来看一段简单的php反序列化示例 <?phpclass pingTest {public $ipAddress "127.0.0.1";public $isValid False;public $output…

Portal-Basic Java Web 应用开发框架:应用篇(八) —— 整合 Freemarker

Portal-Basic Java Web应用开发框架&#xff08;简称 Portal-Basic&#xff09;是一套功能完备的高性能Full-Stack Web应用开发框架&#xff0c;内置稳定高效的MVC基础架构和DAO框架&#xff08;已内置Hibernate、MyBatis和JDBC支持&#xff09;&#xff0c;集成 Action拦截、F…

日常遇到的小问题

日常开发过程中&#xff0c;总会遇到各种小问题&#xff0c;特此记录下各种解决。 1. eclipse中部署项目到tomcat&#xff0c;启动tomcat时报错&#xff1a;  Resource is out of sync with the file system: ................ 太长只截取前一段&#xff0c;解决办法&#xff…

原始套接字抓取所有以太网数据包与分析

If you have any idea, just send comments to me. ####1.原始套接字介绍 关于socket使用客户机/服务器模型的 SOCK_STREAM 或者 SOCK_DGRAM 用于 TCP 和 UDP 连接的应用更为普遍一些&#xff0c;而如果考虑到从网卡中直接捕获原始报文数据就需要用到原始套接字 SOCK_RAW 类型…

Go在谷歌:以软件工程为目的的语言设计

From: http://www.oschina.net/translate/go-at-google-language-design-in-the-service-of-software-engineering 1. 摘要 (本文是根据Rob Pike于2012年10月25日在Tucson, Arizona举行的SPLASH 2012大会上所做的主题演讲进行修改后所撰写的。) 针对我们在Google公司内开发软件…

微信小程序,用户拒绝授权后重新授权;uni-app小程序,用户拒绝授权后点击无效;重新进入后拉起位置授权框;

问题&#xff1a;当用户第一次进入小程序&#xff0c;点击授权按钮后&#xff0c;点了拒绝&#xff0c;再次点击不会出现授权页面&#xff0c;只有再次进入小程序的时候&#xff0c;才会出发请求授权 。 案例&#xff1a; 假如我们获取微信位置&#xff0c;第一次点击的时候弹起…

运维工程师必会的109个Linux命令

运维工程师必会的109个Linux命令 版本1.0 崔存新 更新于2009-12-26 目录 1 文件管理 6 1.1 basename 6 1.2 cat 6 1.3 cd 7 1.4 chgrp 7 1.5 chmod 8 1.6 chown 9 1.7 comm 10 1.8 cp 10 1.9 cut 11 1.10 dd 12 1.11 diff 13 1.12 dir 14 1.13 dos2unix 16 1.14 egrep 17 1.15…

网卡混杂模式介绍与设置

1.混杂模式介绍 混杂模式就是接收所有经过网卡的数据包&#xff0c;包括不是发给本机的包。默认情况下网卡只把发给本机的包&#xff08;包括广播包&#xff09;传递给上层程序&#xff0c;其它的包一律丢弃。简单的讲,混杂模式就是指网卡能接受所有通过它的数据流&#xff0c…

eclipse使用技巧---使用正则表达式查找替换

1&#xff0c;Eclipse ctrlf 打开查找框2&#xff0c;选中 Regular expressions (正则表达式)去掉/* */(eclipse) /\*(.|[\r\n])*?\*/去掉//(eclipse) //.*$去掉import(eclipse) import.*$去掉空行(eclipse) ^\s*\n去掉空行(ue) …

​浅拷贝与深拷贝​

浅拷贝 与深拷贝 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined&#xff0c;Symbol)和对象数据类型。 基本数据类型的特点&#xff1a;直接存储在栈(stack)中的数据 引用数据类型的特点&#xff1a;存储的是该对象在栈中引用&#xff0c;真实…

更改微信小程序的基础版本库;更改uni-app小程序基础库;更改用户的微信小程序基础库最低版本;设置用户的微信小程序版本库;

需求场景&#xff1a;微信小程序不少API都有最低版本支持&#xff0c;为了避免不必要的麻烦&#xff0c;我们可以根据需要给小程序设置基础库最低版本&#xff0c;这样若用户使用的基础库版本低于设置的最低版本要求&#xff0c;则无法正常使用小程序&#xff0c;并提示更新微信…