如何获得线程的状态的方法
不管是Windows API还是MFC的CWinThread类都没有给出直接获得线程状态的接口或函数。线程的状态分为正在执行、挂起、已经结束三种。利用API函数GetExitCodeThread()时获得的返回码只能判定线程是活着的还是已经结束了,这里“活着的”指的是正在执行或挂起状态。那么如果一个线程还活着,怎样鉴别一个线程是正在执行还是正在挂起呢???令人遗憾的是,微软没有给出直接的接口函数。首先,介绍一下MFC创建一个线程的方法,一般采用全局函数AfxBeginThread()函数,该函数有两种形式,分别对应工作者线程和界面线程。
程序代码:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
通常情况下,创建一个线程时线程即开始运行(而不是挂起)并返回一个CWinThread类型指针。由于MFC机制中当线程结束后,返回的CWinThread类型对象将被自动清除,在这种情况下,再访问返回的CWinThread类型对象时将产生访问非法错误。下面的代码演示了一种创建一种开始挂起的线程,并设置返回的CWinThread类型对象的bAutoDelete为false以禁止MFC在线程结束时自动清除该对象,之后再唤醒该线程使之执行。
程序代码:
pThread=AfxBeginThread(ThreadFunc,(LPVOID)0,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); pThread->m_bAutoDelete=FALSE; int suspendCnt=pThread->ResumeThread();
回到帖子开头提出的问题,既然WindowsAPI和MFC都没给出直接返回线程状态的接口函数,还好MFC里有两个函数SuspendThread()和ResumeThread()。
微软给每个线程维护着一个叫做挂起次数计数器的东西,这个在上面两个函数中有大用处。
SuspendThread()是使线程挂起,调用后,返回该次调用之前的挂起计数值,然后挂起计数值加1。如果返回为0,则表示线程原先正在执行,现在进入挂起状态。
而ResumeThread()是使线程唤醒,调用该函数后,线程此时并不一定能摆脱挂起状态。调用该函数后,返回该次调用之前的挂起计数值,然后挂起计数值减1,如果是原先挂起计数值已经为0则保持0值。如果返回值为1,则表示线程原先被挂起,现在转入正在执行状态。如果返回为0,则表示线程原先就处于正在执行状态,现在也继续执行。当返回值大于1时,挂起技术值减1,但线程将依旧被挂起,在这种情况下,只有继续调用几次该函数制止返回值为1,线程才能拜托挂起继续执行。
自己开发了一个Demo验证了上述的规则。需要源代码的发E-mail至worm.msblast@
[ 本帖最后由 hlmzrdongdong 于 2012-10-3 23:23 编辑 ]