Files
GdCpp12/staticOnly/KsMFC/CMFCThread.h

111 lines
2.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}
}
};