基於MFC的編寫線程快速入門

來源:互聯網
上載者:User

基於MFC的編寫線程快速入門 
程式員之家 作者:不詳 日期:2003-2-1 19:19:00

--------------------------------------------------------------------------------
 
對於新手,編寫線程,不知從何下手,不知編寫線程要做那些,下面給出一個線程的簡要架構

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

//定義線程類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();
// Overrides
 // 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 _DEBUG
#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:  perform and per-thread initialization here
 // avoid entering standard message loop by returning FALSE
 return TRUE;  //使用者介面線程,必須返回TRUE
   
     //如是 背景工作執行緒,代碼如下
     /*
     while (WaitForSingleObject(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用了標準的Windows訊息迴圈來處理資料發送和接收入
  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);

//其他代碼

}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.