使用Windows API实现自定义线程类CThread

我们在使用QThread的时候,只需要继承QThread重新实现 run() 函数就可以了,使用起来很方便,接下来就介绍一种实现自定义的类 CThread ,只要继承 CThread 后,重新实现 run() 函数即可。
关于 QThread 的使用可以参见 使用Qt中的QThread创建线程
或者访问我的 个人博客主页 不会飞的纸飞机 ,导航栏中点击多线程,然后也可以看到这篇文章 使用Qt中的QThread创建线程


首先看一下继承 CThread 的子类,CalcSumThread (主要实现计算前100个数的和)的实现:
头文件定义:

#ifndef CALCSUMTHREAD_H
#define CALCSUMTHREAD_H

#include "CThread.h"
class CalcSumThread : public CThread
{
public:
	CalcSumThread();
	~CalcSumThread();
	
	// 重写run函数,实现计算0~100个数的和
	void run(void) override;
};
#endif

run 函数中的实现:

void CalcSumThread::run(void)
{
	int sum = 0;
	for (int i = 0; i <= 100; ++i)
		sum += i;

	std::cout << "Current Thread ID is " << ::GetCurrentThreadId() << ", Result is " << sum << std::endl;
}

调用部分:

CalcSumThread* thread = new CalcSumThread;
thread->start();	// 开启线程
thread->wait();		// 等待线程结束

运行结果:
Created Thread Success, Id is 22200
Current Thread ID is 22200, Result is 5050

函数 start() 表示开启线程(激活线程为可执行状态)
函数 wait() 表示阻塞等待线程退出(同 std::thread 的 join函数)


那么这个 CThread 到底时怎么实现的呢?
下面是 CThread 的完整实现:
头文件定义:

#ifndef CTHREAD_H
#define CTHREAD_H

#include <Windows.h>

class CThread
{
public:
	CThread();
	~CThread();

	// 线程入口函数
	virtual void run(void) = 0;

	// 启动线程
	void start(void);

	// 等待线程函数
	void wait(void);

private:
	static DWORD WINAPI threadProc(LPVOID lpParameters);
	// 创建线程
	void create(void);

	// 线程ID
	DWORD m_nThreadId = 0;
	// 判断线程是否创建成功
	bool m_isCreatedSuccess = true;
	// 线程句柄
	HANDLE m_threadHandle = nullptr;
};
#endif

源文件:

#include "CThread.h"
#include <iostream>

CThread::CThread()
{
	create();
}

CThread::~CThread()
{

}

void CThread::create(void)
{
	// 创建线程
	HANDLE handle = ::CreateThread(nullptr, 0, CThread::threadProc, this, CREATE_SUSPENDED, &m_nThreadId);

	// 判断是否创建成功
	if (handle)
	{
		m_isCreatedSuccess = true;
		std::cout << "Created Thread Success, Id is " << m_nThreadId << std::endl;
	}
	else
	{
		std::cout << "Created Thread Failed!!!" << std::endl;
		m_isCreatedSuccess = false;
	}

	m_threadHandle = handle;
}

// 启动线程
void CThread::start(void)
{
	if (!m_isCreatedSuccess)
		return;

	// 启动线程
	::ResumeThread(m_threadHandle);
}

// 等待线程函数
void CThread::wait(void)
{
	if (!m_isCreatedSuccess)
		return;

	::WaitForSingleObject(m_threadHandle, INFINITE);
}

DWORD WINAPI CThread::threadProc(LPVOID lpParameters)
{
	CThread* thisPointer = (CThread*)lpParameters;

	// 判断线程是否创建成功
	if (!thisPointer->m_isCreatedSuccess)
		return 1;

	// 执行自定义入口函数
	thisPointer->run();
	return 0;
}

本质上是使用了一个静态函数作为线程的入口函数,将 this 指针作为函数的参数传入。如果不是静态函数,c++本质上会把非静态函数默认传递一个 this 指针作为参数,不符合线程入口函数的函数指针类型定义,因此此处必须为静态函数。

这里使用参数 CREATE_SUSPENDED 表示,表示创建线程后不立即执行,挂起该线程。

  • start() 函数,启动线程;使用函数 ResumeThread() 表示将线程从挂起状态变为激活状态,操作系统有一个线程挂起参数,当该参数为0时,线程变为激活状态。使用函数 SuspendThread() 是将该参数+1,使用函数 ResumeThread() 是将该参数-1 。
  • threadProc() ,线程入口函数,将参数转为 this ,然后调用虚函数 run()
  • wait() 函数,阻塞等待线程执行完成。使用 WaitForSingleObject() 这个Windows API 实现。

作者:douzhq
个人博客:http://www.feijiblog.com
文章同步(可下载完整代码):http://www.feijiblog.com/blog/threadmythread

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值