#pragma once //#include "FiberCamera_Exports.h" #include #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 func) : _Run(func) { } protected: /// 主循环函数,可以指定静态函数或、类成员函数、lambda函数 std::function _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; } } };