VC多線程臨界區)

來源:互聯網
上載者:User
      在使用多線程時,一般很少有多個線程完全獨立的工作。往往是多個線程同時操作一個全域變數來擷取程式的運行結果。多個線程同時訪問同一個全域變數,如果都是讀取操作,則不會出現問題。如果是寫操作,則會發生錯誤。這時候,我們可以通過臨界區,為全域變數設定一個保護,保證同時只有一個線程可以訪問此變數,其他變數進入等待狀態。
      臨界區(Critical Section)是一段獨佔對某些共用資源訪問的代碼,在任意時刻只允許一個線程對共用資源進行訪問。如果有多個線程試圖同時訪問臨界區,那麼在有一個線程進入後其他所有試圖訪問此臨界區的線程將被掛起,並一直持續到進入臨界區的線程離開。臨界區在被釋放後,其他線程可以繼續搶佔,並以此達到用原子方式操作共用資源的目的。
      臨界區在使用時以CRITICAL_SECTION結構對象保護共用資源,並分別用 ①InitializeCriticalSection(&cs); //初始化臨界區②EnterCriticalSection(&cs);//進入臨界區③LeaveCriticalSection(&cs);//離開臨界區④DeleteCriticalSection(&cs);//刪除臨界區 
      一般類程式(舉例)// 臨界區結構對象
CRITICAL_SECTION g_cs;
// 共用資源 
char g_cArray[10]

UINT ThreadProc1(LPVOID pParam)
{
 // 進入臨界區
 EnterCriticalSection(&g_cs);
 // 對共用資源進行寫入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[i] = ’a’;
  Sleep(1);
 }
 // 離開臨界區
 LeaveCriticalSection(&g_cs);
 return 0;
}

UINT ThreadProc2(LPVOID pParam)
{
 // 進入臨界區
 EnterCriticalSection(&g_cs);
 // 對共用資源進行寫入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[10 - i - 1] = ’b’;
  Sleep(1);
 }
 // 離開臨界區
 LeaveCriticalSection(&g_cs);
 return 0;
}

void CSampleView::OnCriticalSection() 
{
 // 初始化臨界區
 InitializeCriticalSection(&g_cs);
 // 啟動線程
 AfxBeginThread(ThreadProc1, NULL);
 AfxBeginThread(ThreadProc2, NULL);
 // 等待計算完畢
 Sleep(300);
 // 報告計算結果
 CString sResult = CString(g_cArray);
 AfxMessageBox(sResult);
}

      在使用臨界區時,一般不允許其已耗用時間過長,只要進入臨界區的線程還沒有離開,其他所有試圖進入此臨界區的線程都會被掛起而進入到等待狀態,並會在一定程度上影響。程式的運行效能。尤其需要注意的是不要將等待使用者輸入或是其他一些外界幹預的操作包含到臨界區。如果進入了臨界區卻一直沒有釋放,同樣也會引起其他線程的長時間等待。換句話說,在執行了EnterCriticalSection()語句進入臨界區後無論發生什麼,必須確保與之匹配的LeaveCriticalSection()都能夠被執行到。可以通過添加結構化異常處理代碼來確保LeaveCriticalSection ()語句的執行。雖然臨界區同步速度很快,但卻只能用來同步本進程內的線程,而不可用來同步多個進程中的線程。
      

      MFC為臨界區提供有一個CCriticalSection類,使用該類進行線程同步處理是非常簡單的,只需線上程函數中用CCriticalSection類成員函數 Lock()和UnLock()標定出被保護程式碼片段即可。對於上述代碼,可通過CCriticalSection類將其改寫如下:

       MFC應用(舉例)

// MFC臨界區類對象
CCriticalSection g_cs;
// 共用資源 
char g_cArray[10];
UINT ThreadProc1(LPVOID pParam)
{
 // 進入臨界區
 g_cs.Lock();
 // 對共用資源進行寫入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[i] = ’a’;
  Sleep(1);
 }
 // 離開臨界區
 g_cs.Unlock();
 return 0;
}
UINT ThreadProc2(LPVOID pParam)
{
 // 進入臨界區
 g_cs.Lock();
 // 對共用資源進行寫入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[10 - i - 1] = ’b’;
  Sleep(1);
 }
 // 離開臨界區
 g_cs.Unlock();
 return 0;
}
void CSampleView::OnCriticalSectionMfc() 
{
 // 啟動線程
 AfxBeginThread(ThreadProc1, NULL);
 AfxBeginThread(ThreadProc2, NULL);
 // 等待計算完畢
 Sleep(300);
 // 報告計算結果
 CString sResult = CString(g_cArray);
 AfxMessageBox(sResult);
}

 轉自:http://www.cnblogs.com/userinterface/archive/2005/04/27/146137.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.