基於MFC的編寫執行緒快速入門 (轉)

worldblog發表於2007-12-12
基於MFC的編寫執行緒快速入門 (轉)[@more@]

對於新手,編寫執行緒,不知從何下手,不知編寫執行緒要做那些,下面給出一個執行緒的簡要

//////////////////////////////////////////////////////////////

//定義執行緒類YourThread.h
#if !defined(YOURTHREAD_INCLUDE_FILE)
#define YOURTHREAD_INCLUDE_FILE

  class CYourThread :public CWinThread
{
 ....
 DECLARE_DYNCREATE(CYourThread)
public:
 CYourThread();  // protected constructor used by dynamic creation

// Attributes
public:
  int m_bCloseFlag;
  HANDLE m_hEventKill;
  HANDLE m_hEventDead;
//操件
public:
  void KillThread();  //清除本執行緒

protected:
 virtual void SingleStep();
 virtual void Delete();
// Overrs
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CEgClientCacheThread)
 public:
 virtual BOOL InitInstance();
 virtual int ExitInstance();
 virtual int Run();
 //}}AFX_VIRTUAL
// Implementation
public:
 virtual ~CYourThread();

 // Generated message map functions
 //{{AFX_MSG(CEgClientCacheThread)
 // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()
}
#ednif

////////////////////////////////////////////
//實現YourThread.cpp
#include "stdafx.h"
#include "YourThread.h"

#ifdef _DE
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CYourThread, CWinThread)
CYourThread::CYourThread()
{
 m_bAutoDelete = FALSE;  //注:該成員為CWinThread的成員,如為TRUE,在CWinThread::Delete()將刪除執行緒
  //置為FALSE不允許自動刪除執行緒自已

 m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL);
 m_hEventDead = CreateEvent(NULL, TRUE, FALSE, NULL);
}

CYourThread::~CYourThread()
{

 CloseHandle(m_hEventKill);
 CloseHandle(m_hEventDead);
}
BOOL cYourThread::InitInstance()
{
 // TODO:  perfoand per-thread initialization here
 // avoid entering standard message l by returning FALSE
 return TRUE;  //介面執行緒,必須返回TRUE
 
  //如是 工作執行緒,程式碼如下
  /*
  while (WaitForSingle(m_hEventKill, 0) == WAIT_TIMEOUT)
   SingleStep();
 // 避免進入標準訊息迴圈,必須返回FALSE
     return FALSE;
  */
}

CYourThread:SingleStep()
{
  //你的執行緒必一次的任務,每一次你的執行緒得到控制權,都會執行這個。
}

//如是使用者介面執行緒,必須過載下面的函式
int CYourThread:Run
{
  //注:正面的程式碼 除了加註中文解釋的外,其他的與CWinThread::Run()是完全一致的
  // for tracking the idle time state
 ASSERT_VALID(this);

 // for tracking the idle time state
 BOOL bIdle = TRUE;
 LONG lIdleCount = 0;

 // acquire and dispatch messages until a WM_QUIT message is received.
 for (;;)
 {
 SingleStep(); //執行本執行緒的單步函式
  if(m_bCloseFlag ==TRUE) //指示執行緒關閉
 {
  return ExitInstance();
 }
 // phase2: pump messages while available
  //必須用下列方式進行訊息迴圈,因為CAsyncSocket用了標準的訊息迴圈來處理資料傳送和接收入
 while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))  //必須先用PeekMessage進行訊息檢查
 {
 if(!(::GetMessage(&m_msgCur, NULL, NULL, NULL)))  //取訊息
 return ExitInstance();

 if (!PreTranslateMessage(&m_msgCur))
 {
  ::TranslateMessage(&m_msgCur);
  ::DispatchMessage(&m_msgCur);
 }

  if (IsIdleMessage(&m_msgCur))
 {
 bIdle = TRUE;
 lIdleCount = 0;
 }

 }
 
 } 
 return ExitInstance();

}

int CYourThread::ExitInstance()
{
  //如是使用者介面執行緒,此處完成你的清除任務

 VERIFY(SetEvent(m_hEventDead)); //這一句只有使用者介面執行緒需要

 return CWinThread::ExitInstance();

  }

void CYourThread::Delete()
{
 // calling the base here won't do anything but it is a good habit?????????????

 //在CWinThread::Delete()如m_hAutoDelete為TRUE,則會刪掉本程式
 CWinThread::Delete();

 // acknowledge receipt of kill notification
 VERIFY(SetEvent(m_hEventDead));
}

void CYourThread::KillThread()
{
 // Note: this function is called in the context of other threads,
 //  not the thread itself.

 // reset the m_hEventKill which signals the thread to shutdown
 VERIFY(SetEvent(m_hEventKill));

 // allow thread to run at higher priority during kill process
 SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
 WaitForSingleObject(m_hEventDead, INFINITE);

  //下面兩行只有工作執行緒才能要
  /*
 WaitForSingleObject(m_hThread, INFINITE);
 delete this;
  */
}
////////////////////////////////////////////////
//啟動執行緒
void startYourThread()
{
 CEgYourThread *pThread;
  if(!(pThread = (CYourThread*)AfxBeginThread(RUNTIME_CLASS(CYourThread),
  THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED)))
  {
 AfxMessageBox(_T("建立執行緒失敗"));
 return ;
  }

VERIFY(pThread->SetThreadPriority(THREAD_PRIORITY_IDLE));  //設定優先順序
 
 pEgThread->ResumeThread();  //啟動執行緒
  }

///////////////////////////////////////////////////////
//下面是解釋
注意:
 1   執行緒分兩類: 工作執行緒 和 使用者介面執行緒

 2  使用者介面執行緒可以進行有如鍵盤輸入的使用者互動,而工作執行緒則沒有。當然正在訊息處理機制上也有差異。
  3 線上程初始化也不同. 如上面的例子
  4 在重複使用的執行緒上,工作執行緒與使用者介面執行緒的清除也不一樣.

 5 多執行緒時,必須解決資源衝突問題,剛開始學寫執行緒時,可以用臨界法來解決這個問題

在外部定義一個全域性變數

  CRITICAL_SECTION  m_csYourThreadLock;  //執行緒同步鎖

  在時初始化:

   InitializeCriticalSection(&m_csYourThreadLock)

 在退出所有執行緒後

 DeleteCriticalSection(&m_csYourThreadLock)

 

在SingleStep()函式中,對共享資源的處理,加上這一臨界鎖

void CYourThread::SingleStep()

{

EnterCriticalSection(&m_csYourThreadLock);

// 共享資源處理程式碼

LeaveCriticalSection(&m_csYourThreadLock);

//其他程式碼

}

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992335/,如需轉載,請註明出處,否則將追究法律責任。

相關文章