111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#pragma once
|
||
//#include "FiberCamera_Exports.h"
|
||
#include <afxwin.h>
|
||
|
||
#ifndef WM_QUIT_THREAD
|
||
#define WM_QUIT_THREAD (WM_USER +0)
|
||
#endif
|
||
|
||
/// \brief 工作线程类。
|
||
/// 多线程有多种实现方式,本类适合:
|
||
/// 1. 指定一个函数作为线程的主循环。
|
||
/// 2. 需要用到windows的消息系统。
|
||
///
|
||
/// 简单用法:
|
||
/// 1. 工作类相关的某个类里定义一个成员:
|
||
/// CMFCThread * m_Thread;
|
||
///
|
||
/// 2. 构造实例,但未启动线程:
|
||
/// m_Thread = new CMFCThread(<静态函数指针>);
|
||
/// 或:
|
||
/// m_Thread = new CMFCThread(std::bind(<类成员函数指针>, this));
|
||
///
|
||
///
|
||
/// 3. 启动线程:
|
||
/// if(m_Thread){
|
||
/// m_Thread->Start();
|
||
/// }
|
||
///
|
||
/// 4. 终止线程:
|
||
/// if(m_Thread){
|
||
/// m_Thread->Quit();
|
||
/// }
|
||
|
||
class CMFCThread :
|
||
public CWinThread // 继承CWinThread的目的是需要用到windows的消息系统
|
||
{
|
||
public:
|
||
// DECLARE_DYNAMIC(CMFCThread) // 需要MFC的动态类型信息时打开。本类只创建实例指针,不需要动态类型信息。
|
||
|
||
using run_func_t = int(void);
|
||
|
||
/// @brief 用静态函数指针构造工作线程实例
|
||
/// @param func
|
||
CMFCThread(run_func_t* func)
|
||
: _Run(func)
|
||
{
|
||
|
||
}
|
||
|
||
/// @brief 用bind()封装类成员函数、lambda函数等
|
||
/// @param func
|
||
CMFCThread(std::function<int()> func)
|
||
: _Run(func)
|
||
{
|
||
|
||
}
|
||
|
||
protected:
|
||
/// 主循环函数,可以指定静态函数或、类成员函数、lambda函数
|
||
std::function<int()> _Run;
|
||
|
||
/// 直接返回TRUE,缺省不会进run()而是进入CWinThread的消息循环
|
||
virtual BOOL InitInstance()
|
||
{
|
||
return TRUE;
|
||
//return CWinThread::InitInstance();
|
||
}
|
||
|
||
public:
|
||
/// @brief 线程主函数,内部改成了函数调用,方便简单应用场景不需要再重载。
|
||
virtual int Run() override
|
||
{
|
||
ASSERT(_Run != nullptr); // 使用前必须设置函数指针
|
||
return _Run();
|
||
}
|
||
|
||
/// @brief 设置函数指针和优先级
|
||
/// @param prio 线程优先级,默认THREAD_PRIORITY_NORMAL。
|
||
bool Start(int prio = THREAD_PRIORITY_NORMAL) {
|
||
if (CreateThread()) {
|
||
if (prio != THREAD_PRIORITY_NORMAL) {
|
||
SetThreadPriority(prio);
|
||
}
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// @brief 外部调用结束线程
|
||
void Quit(int ret=0) {
|
||
if(m_nThreadID) ::PostThreadMessage(m_nThreadID, WM_QUIT_THREAD, WPARAM(ret), 0);
|
||
}
|
||
|
||
/// @brief 等待线程结束。与Quit()分开方便先所有子线程调用一遍Quit(),再一个个等。
|
||
/// @param ms 等待时间,单位毫秒
|
||
bool Wait(int ms) {
|
||
DWORD uResult = WaitForSingleObject(this->m_hThread, ms);
|
||
if(WAIT_OBJECT_0 == uResult) {
|
||
//alog->info(u8"线程正常退出");
|
||
return true;
|
||
}
|
||
else {
|
||
alog->warn(u8"线程退出超时 {}", uResult);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
};
|