// NonMfcThreadTest1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <process.h> void fnThread(void * pPara); /** * @note 线程函数一定是要入参的 * 线程函数没有入参指针时的编译错误 * error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void)' * to 'void (__cdecl *)(void *)' */ //void fnThread(); int main(int argc, char* argv[]) { Beep(100, 200); printf("Hello World!/n"); /** * 要使用线程函数 _beginthread, 需要打开下面选项: * Project>>Settings>>c/c++>>Use run-time libray>> Multithreaded DLL * 如果IDE设置是Single-Threaded*, 有编译错误 * error C2065: '_beginthread' : undeclared identifier */ _beginthread(fnThread, 0, NULL); MessageBox(NULL, "<< Main", "", IDOK); return 0; } void fnThread(void * pPara) { while(1) { Beep(100, 200); Sleep(200); DeleteFile("c://tmp//test.txt"); //c://tmp//test.txt, 手工建立这个文件, //如果被删掉, 说明线程还在运行 } /** * 通过Beep和手工拷贝临时文件的结果, 得出结论 * 当主线程退出时, 线程被强行进程结束掉了, * 线程开辟的资源得不到释放 * 不可能达到主程序退出时, 留下一个工作线程在干活的效果 */ MessageBox(NULL, "fnThread Quit", "", IDOK); }
<2011_0324>
/*****************************************************************************/ <2011_0324_0013><home><LostSpeed><Threadwrapper V1.0.0.1> * Threadwrapper 封装了一个线程基类, 控制线程的建立, 运行, 暂停, 继续, 停止 提供了线程实现为虚函数, 使用户专注于线程逻辑的实现. /*****************************************************************************/
// SrcThreadwrapper.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "SrcThreadwrapper.h" #include "ThreadwrapperApp1.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; int fnTestMyThread(); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { // TODO: code your application's behavior here. CString strHello; strHello.LoadString(IDS_HELLO); cout << (LPCTSTR)strHello << endl; fnTestMyThread(); } printf("END"); getchar(); return nRetCode; } int fnTestMyThread() { /** * test CThreadwrapperApp1, ours thread from CThreadwrapperBase */ int nSleepCnt = 3000; CThreadwrapperApp1 ThreadwrapperApp1; Sleep(nSleepCnt); ThreadwrapperApp1.CreateThreadProc(); Sleep(nSleepCnt); ThreadwrapperApp1.RunThreadProc(); Sleep(nSleepCnt); ThreadwrapperApp1.PauseThreadProc(); Sleep(nSleepCnt); ThreadwrapperApp1.ContinueThreadProc(); Sleep(nSleepCnt); ThreadwrapperApp1.StopThreadProc(); Sleep(nSleepCnt); return S_OK; }
// ThreadwrapperApp1.h: interface for the CThreadwrapperApp1 class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_THREADWRAPPERAPP1_H__78952616_8587_46EB_9735_0DD38A4A2042__INCLUDED_) #define AFX_THREADWRAPPERAPP1_H__78952616_8587_46EB_9735_0DD38A4A2042__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ThreadwrapperBase.h" class CThreadwrapperApp1 : public CThreadwrapperBase { public: CThreadwrapperApp1(); virtual ~CThreadwrapperApp1(); virtual UINT ThreadProc(void); int dosomething(int nStepSn); BOOL m_bTaskWasFinished; }; #endif // !defined(AFX_THREADWRAPPERAPP1_H__78952616_8587_46EB_9735_0DD38A4A2042__INCLUDED_)
// ThreadwrapperApp1.cpp: implementation of the CThreadwrapperApp1 class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SrcThreadwrapper.h" #include "ThreadwrapperApp1.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CThreadwrapperApp1::CThreadwrapperApp1() { m_bTaskWasFinished = FALSE; } CThreadwrapperApp1::~CThreadwrapperApp1() { } UINT CThreadwrapperApp1::ThreadProc(void) { /** * 继承自这个线程控制类的类实现虚函数ThreadProc完成自己的线程逻辑 * 写法参照下面的示例 */ /** * 任务如果没有完成, 检测是否需要退出 * 如果需要退出, 则退出, 使线程响应迅速 */ int nStepSn = 0; while(S_OK != IsNeedStop()) { printf(">> CThreadwrapperApp1::ThreadProc running.../n"); Sleep(10);/**< 留出时间片给系统, 避免CPU占用率过高 */ /** * 任务如果完成, 可以主动退出 * * 没有接到调用者的停止命令, 继续任务 * * 为了使线程响应迅速, 应该减少dosomething()的执行时间 * 或者把一个大任务分解成许多的小任务 */ if(m_bTaskWasFinished) break; else dosomething(nStepSn++); } return S_OK; } int CThreadwrapperApp1::dosomething(int nStepSn) { int n = 0; if(nStepSn > 20) { m_bTaskWasFinished = TRUE; } printf(">> process Setp[%d]/n", nStepSn); Sleep(n * 100); printf("<< process Setp[%d]/n", nStepSn); return S_OK; }
// ThreadwrapperBase.h: interface for the CThreadwrapperBase class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_THREADWRAPPERBASE_H__CE04C904_61E6_4453_9AC8_C514E131A06E__INCLUDED_) #define AFX_THREADWRAPPERBASE_H__CE04C904_61E6_4453_9AC8_C514E131A06E__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CThreadwrapperBase { public: CThreadwrapperBase(); virtual ~CThreadwrapperBase(); public: INT CreateThreadProc(); INT RunThreadProc(); INT PauseThreadProc(); INT ContinueThreadProc(); INT StopThreadProc(); INT IsNeedStop(); INT IsThreadWasStoped(); private: static UINT ThreadProc(LPVOID lpArg); virtual UINT ThreadProc(void); private: CWinThread * m_pWinThread; HANDLE m_hEvent_ThreadProc_NeedStop; DWORD m_dwThreadCnt; }; #endif // !defined(AFX_THREADWRAPPERBASE_H__CE04C904_61E6_4453_9AC8_C514E131A06E__INCLUDED_)
// ThreadwrapperBase.cpp: implementation of the CThreadwrapperBase class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SrcThreadwrapper.h" #include "ThreadwrapperBase.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CThreadwrapperBase::CThreadwrapperBase() { m_dwThreadCnt = 0; m_pWinThread = NULL; m_hEvent_ThreadProc_NeedStop = CreateEvent(NULL, TRUE, FALSE, NULL); } CThreadwrapperBase::~CThreadwrapperBase() { if(S_OK != IsThreadWasStoped()) { StopThreadProc(); } } INT CThreadwrapperBase::IsNeedStop() { return (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent_ThreadProc_NeedStop, 1)) ? S_OK : S_FALSE; } INT CThreadwrapperBase::IsThreadWasStoped() { if(!m_pWinThread) return S_OK;/**< Thread never run */ return (WAIT_OBJECT_0 == WaitForSingleObject(m_pWinThread->m_hThread, 1)) ? S_OK : S_FALSE; } INT CThreadwrapperBase::CreateThreadProc() { printf(">> CThreadwrapperBase::CreateThreadProc()/n"); if(m_pWinThread && (S_OK != IsThreadWasStoped())) return S_OK;/**< thread running or pause */ /** * thread never run or thread finished by itself */ ResetEvent(m_hEvent_ThreadProc_NeedStop); m_pWinThread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); ASSERT(m_pWinThread); m_pWinThread->m_bAutoDelete = FALSE;/**< important! */ return S_OK; } INT CThreadwrapperBase::RunThreadProc() { printf(">> CThreadwrapperBase::RunThreadProc()/n"); INT nRc = 0; if(m_pWinThread) { ContinueThreadProc(); //nRc = m_pWinThread->Run(); } else return S_FALSE; return S_OK; } INT CThreadwrapperBase::PauseThreadProc() { printf(">> CThreadwrapperBase::PauseThreadProc()/n"); if(!m_pWinThread) return S_FALSE; /** * msdn say: * Increments the current thread’s suspend count. * If any thread has a suspend count above zero, that thread does not execute. */ m_dwThreadCnt = m_pWinThread->SuspendThread(); return (m_dwThreadCnt > 0) ? S_OK : S_FALSE; } INT CThreadwrapperBase::ContinueThreadProc() { printf(">> CThreadwrapperBase::ContinueThreadProc()/n"); if(!m_pWinThread) return S_FALSE; m_dwThreadCnt = m_pWinThread->ResumeThread(); /** * msdn say: * If the return value is one, the thread was suspended, but is now restarted. * Any return value greater than one means the thread remains suspended. */ return (1 == m_dwThreadCnt) ? S_OK : S_FALSE; } INT CThreadwrapperBase::StopThreadProc() { printf(">> CThreadwrapperBase::StopThreadProc()/n"); if(!m_pWinThread) return S_OK; SetEvent(m_hEvent_ThreadProc_NeedStop); WaitForSingleObject(m_pWinThread->m_hThread, INFINITE); delete m_pWinThread; m_pWinThread = NULL; return S_OK; } UINT CThreadwrapperBase::ThreadProc(LPVOID lpArg) { if(!lpArg) return S_FALSE; CThreadwrapperBase * pThis = (CThreadwrapperBase *)(lpArg); return pThis->ThreadProc(); } UINT CThreadwrapperBase::ThreadProc(void) { /** * 继承自这个线程控制类的类实现虚函数ThreadProc完成自己的线程逻辑 * 写法参照下面的示例 */ /** * 任务如果没有完成, 检测是否需要退出 * 如果需要退出, 则退出, 使线程响应迅速 */ while(S_OK != IsNeedStop()) { printf(">> CThreadwrapperBase::ThreadProc running/n"); Sleep(10);/**< 留出时间片给系统, 避免CPU占用率过高 */ /** * 任务如果完成, 可以主动退出 * * 没有接到调用者的停止命令, 继续任务 * * 为了使线程响应迅速, 应该减少dosomething()的执行时间 * 或者把一个大任务分解成许多的小任务 */ //下面是伪码 //if(bTaskWasFinished) // break; //else // dosomething(); } return S_OK; }