我们在使用QThread的时候,只需要继承QThread重新实现 run() 函数就可以了,使用起来很方便,
接下来就介绍一种实现自定义的类 CThread ,只要继承 CThread 后,
重新实现 run() 函数即可。
关于 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 指针作为参数, 不符合线程入口函数的函数指针类型定义,因此此处必须为静态函数。