⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.h

📁 remote debug and compile tools
💻 H
字号:
#if !defined(AFX_THREAD_H__20000927_7992_09B2_A0EF_0080AD509054__INCLUDED_)
#define AFX_THREAD_H__20000927_7992_09B2_A0EF_0080AD509054__INCLUDED_

#pragma once

/////////////////////////////////////////////////////////////////////////////
// Thread - wrapper for Thread API
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#if defined(_MT) || defined(_DLL)
// Due to the nature of the multithreaded C runtime lib we
// need to use _beginthreadex() and _endthreadex() instead
// of CreateThread() and ExitThread(). See Q104641.
#include <process.h>
#endif

#ifndef ATLTRY
   #define ATLTRY(x) (x)
#endif


/////////////////////////////////////////////////////////////////////////////
// CThread

template< bool t_bManaged >
class CThreadT
{
public:
   HANDLE m_hThread;
   bool m_bSuspended;

   CThreadT(HANDLE hThread = NULL) : m_hThread(hThread), m_bSuspended(false)
   {
   }
   virtual ~CThreadT()
   {
      if( t_bManaged ) Release();
   }
   BOOL Create(LPTHREAD_START_ROUTINE pThreadProc, 
               LPVOID pParam = NULL, 
               int iPriority = THREAD_PRIORITY_NORMAL)
   {
      _ASSERTE(m_hThread==NULL);
      _ASSERTE(pThreadProc);
      DWORD dwThreadID;
#if defined(_MT) || defined(_DLL)
      m_hThread = (HANDLE) _beginthreadex(NULL, 0, (UINT (WINAPI*)(void*)) pThreadProc, pParam, CREATE_SUSPENDED, (UINT*) &dwThreadID);
#else
      m_hThread = ::CreateThread(NULL, 0, pThreadProc, pParam, CREATE_SUSPENDED, &dwThreadID);
#endif
      if( m_hThread == NULL ) return FALSE;
      if( iPriority != THREAD_PRIORITY_NORMAL ) {
         if( !::SetThreadPriority(m_hThread, iPriority) ) {
            _ASSERTE(!"Couldn't set thread priority");
         }
      }
      return ::ResumeThread(m_hThread) != (DWORD) -1;
   }
   BOOL Release()
   {
      if( m_hThread == NULL ) return TRUE;
      if( ::CloseHandle(m_hThread) == FALSE ) return FALSE;
      m_hThread = NULL;
      return TRUE;
   }
   void Attach(HANDLE hThread)
   {
      _ASSERTE(m_hThread==NULL);
      m_hThread = hThread;
   }
   HANDLE Detach()
   {
      HANDLE hThread = m_hThread;
      m_hThread = NULL;
      return hThread;
   }
   BOOL SetPriority(int iPriority) const
   {
      _ASSERTE(m_hThread);
      return ::SetThreadPriority(m_hThread, iPriority);
   }
   int GetPriority() const
   {
      _ASSERTE(m_hThread);
      return ::GetThreadPriority(m_hThread);
   }
   BOOL Suspend()
   {
      _ASSERTE(m_hThread);
      if( m_bSuspended ) return TRUE;
      if( ::SuspendThread(m_hThread) == (DWORD) -1 ) return FALSE;
      m_bSuspended = true;
      return TRUE;
   }
   BOOL Resume()
   {
      _ASSERTE(m_hThread);
      if( !m_bSuspended ) return TRUE;
      if( ::ResumeThread(m_hThread) == (DWORD) -1 ) return FALSE;
      m_bSuspended = false;
      return TRUE;
   }
   BOOL IsSuspended() const
   {
      _ASSERTE(m_hThread);
      return m_bSuspended == true;
   }
   BOOL IsRunning() const
   {
      if( m_hThread == NULL ) return FALSE;
      DWORD dwCode = 0;
      ::GetExitCodeThread(m_hThread, &dwCode);
      return dwCode == STILL_ACTIVE;
   }
   BOOL WaitForThread(DWORD dwTimeout = INFINITE) const
   {
      _ASSERTE(m_hThread);
      return ::WaitForSingleObject(m_hThread, dwTimeout) == WAIT_OBJECT_0;
   }
   BOOL Terminate(DWORD dwExitCode = 0) const
   {
      // See Q254956 why calling this could be a bad idea!
      _ASSERTE(m_hThread);
      return ::TerminateThread(m_hThread, dwExitCode);
   }
   BOOL GetExitCode(DWORD* pExitCode) const
   {
      _ASSERTE(m_hThread);
      _ASSERTE(pExitCode);
      return ::GetExitCodeThread(m_hThread, pExitCode);
   }
#if(WINVER >= 0x0500)
   BOOL GetThreadTimes(LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime) const
   {
      _ASSERTE(m_hThread);
      _ASSERTE(lpExitTime!=NULL && lpKernelTime!=NULL && lpUserTime!=NULL);
      return ::GetThreadTimes(m_hThread, lpExitTime, lpKernelTime, lpUserTime);
   }
#endif
   operator HANDLE() const { return m_hThread; }
};

typedef CThreadT<false> CThreadHandle;
typedef CThreadT<true> CThread;


/////////////////////////////////////////////////////////////////////////////
// CThreadImpl

template< class T >
class CThreadImpl : public CThread
{
public:
   bool volatile m_bStopped; // Signals when thread should stop (thread loop should exit)

   CThreadImpl() : m_bStopped(false)
   {
   }
   virtual ~CThreadImpl()
   {
      // NOTE: Remember destructors cannot call overrides!
      Stop();
   }
   virtual BOOL Start()
   {
      m_bStopped = false;
      if( !Create(ThreadProc, (LPVOID) static_cast<T*>(this) ) ) return FALSE;
      return TRUE;
   }
   virtual void Stop()
   {
      if( !SignalStop() ) return;
      WaitForThread();
      Release();
   }
   BOOL SignalStop()
   {
      if( m_hThread == NULL ) return FALSE;
      m_bStopped = true;
      if( m_bSuspended ) Resume();
      return TRUE;
   }
   BOOL ShouldStop() const
   {
      _ASSERTE(m_hThread);
      return m_bStopped == true;
   }

   static DWORD WINAPI ThreadProc(LPVOID pData)
   {
      T* pThis = static_cast<T*>(pData);
#if defined(_MT) || defined(_DLL)
      ATLTRY(_endthreadex( pThis->Run() ));
      return 0;
#else
      DWORD dwRet = 0;
      ATLTRY(dwRet = pThis->Run());
      return dwRet;
#endif
   }
   DWORD Run()
   {
      _ASSERTE(false); // must override this
/*
      // Sample thread code...
      while( !ShouldStop() ) {
         ...
      }
*/
      return 0;
   }
};


/////////////////////////////////////////////////////////////////////////////
// CEvent

class CEvent
{
public:
   HANDLE m_hEvent;

   CEvent(HANDLE hEvent = INVALID_HANDLE_VALUE) : m_hEvent(hEvent)
   { 
   }
   ~CEvent()
   {
      Close();
   }
   BOOL Create(LPCTSTR pstrName = NULL, BOOL bManualReset = FALSE, BOOL bInitialState = FALSE, LPSECURITY_ATTRIBUTES pEventAttributes = NULL)
   {
      _ASSERTE(pstrName==NULL || !::IsBadStringPtr(pstrName,-1));
      _ASSERTE(m_hEvent==INVALID_HANDLE_VALUE);
      m_hEvent = ::CreateEvent(pEventAttributes, bManualReset, bInitialState, pstrName);
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return m_hEvent != INVALID_HANDLE_VALUE;
   }
   BOOL Open(LPCTSTR pstrName, DWORD dwDesiredAccess = EVENT_ALL_ACCESS, BOOL bInheritHandle = TRUE)
   {
      _ASSERTE(!::IsBadStringPtr(pstrName,-1));
      _ASSERTE(m_hEvent==INVALID_HANDLE_VALUE);
      m_hEvent = ::OpenEvent(dwDesiredAccess, bInheritHandle, pstrName);
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return m_hEvent != INVALID_HANDLE_VALUE;
   }
   BOOL IsOpen() const
   {
      return m_hEvent != INVALID_HANDLE_VALUE;
   }
   void Close()
   {
      if( m_hEvent == INVALID_HANDLE_VALUE ) return;
      ::CloseHandle(m_hEvent);
      m_hEvent = INVALID_HANDLE_VALUE;
   }
   void Attach(HANDLE hEvent)
   {
      _ASSERTE(m_hEvent==INVALID_HANDLE_VALUE);
      m_hEvent= hEvent;
   }  
   HANDLE Detach()
   {
      HANDLE hEvent = m_hEvent;
      m_hEvent = INVALID_HANDLE_VALUE;
      return hEvent;
   }
   BOOL ResetEvent()
   {
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return ::ResetEvent(m_hEvent);
   }
   BOOL SetEvent()
   {
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return ::SetEvent(m_hEvent);
   }
   BOOL PulseEvent()
   {
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return ::PulseEvent(m_hEvent);
   }
   BOOL WaitForEvent(DWORD dwTimeout = INFINITE)
   {
      _ASSERTE(m_hEvent!=INVALID_HANDLE_VALUE);
      return ::WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0;
   }
   operator HANDLE() const { return m_hEvent; }
};


/////////////////////////////////////////////////////////////////////////////
// CCriticalSection

#ifndef __ATLBASE_H__

class CCriticalSection
{
public:
   CRITICAL_SECTION m_sec;

   void Init() 
   {
      ::InitializeCriticalSection(&m_sec);
   }
   void Term() 
   {
      ::DeleteCriticalSection(&m_sec);
   }
   void Lock() 
   {
      ::EnterCriticalSection(&m_sec);
   }
   void Unlock() 
   {
      ::LeaveCriticalSection(&m_sec);
   }
};

class CAutoCriticalSection
{
public:
   CRITICAL_SECTION m_sec;

   CAutoCriticalSection() 
   {
      ::InitializeCriticalSection(&m_sec);
   }
   ~CAutoCriticalSection() 
   {
      ::DeleteCriticalSection(&m_sec);
   }
   void Lock() 
   {
      ::EnterCriticalSection(&m_sec);
   }
   void Unlock() 
   {
      ::LeaveCriticalSection(&m_sec);
   }
};

#endif


#endif // !defined(AFX_THREAD_H__20000927_7992_09B2_A0EF_0080AD509054__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -