線程同步技術

來源:互聯網
上載者:User

(1)互斥對象:函數CreateMutex。在多核下工作不正常。
(2)事件對象:函數CreateEvent、SetEvent、ResetEvent、WaitForSingleObject,應當使用自動重設的事件對象。在多核下工作正常。
(3)關鍵程式碼片段:類CRITICAL_SECTION,函數InitializeCriticalSection、DeleteCriticalSection、EnterCriticalSection、LeaveCriticalSection。在多核下工作基本正常,但是會出現:“"xxx"指令引用的"xxx"記憶體。該記憶體不能為"written"。”。需要注意線程死結問題。

三者比較:
互斥對象和事件對象都屬於核心對象,速度較慢。但可以在多個進程中的各個線程間進行同步。
關鍵程式碼片段工作在使用者方式下,同步速度較快,但容易進入死結狀態,因為在等待進入關鍵程式碼片段時無法設定逾時值。通常,首選關鍵程式碼片段。
其使用也比較簡單,如果在MFC中的話,可在建構函式調用InitializeCriticalSection,在建構函式調用DeleteCriticalSection,在所需保護的代碼前調用EnterCriticalSection,在訪問完所需保護的資源後調用LeaveCriticalSection即可。

 

----------------例子:互斥對象------------------------------------------------

#include <windows.h><br />#include <iostream.h><br />int index=0;<br />int tickets=20;<br />HANDLE hMutex;<br />DWORD WINAPI Fun1Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />WaitForSingleObject(hMutex,INFINITE);<br />if (tickets>0)<br />{<br />Sleep(1);<br /> cout<<"thread 1 sell ticket: "<<tickets--<<endl;<br />}<br />else<br />{<br />break;<br />}<br />ReleaseMutex(hMutex);<br />}<br />return 0;<br />}<br />DWORD WINAPI Fun2Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />WaitForSingleObject(hMutex,INFINITE);<br />if (tickets>0)<br />{<br />Sleep(1);<br />cout<<"thread 2 sell ticket: "<<tickets--<<endl;<br />}<br />else<br />{<br />break;<br />}<br />ReleaseMutex(hMutex);<br />}</p><p>return 0;<br />}<br />void main()<br />{<br />HANDLE hThread1;<br />HANDLE hThread2;<br />hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);<br />hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);<br />CloseHandle(hThread1);<br />CloseHandle(hThread2);<br />hMutex=CreateMutex(NULL,FALSE,NULL);<br />Sleep(1000);<br />}

正確的結果是由20遞減到1,但是本程式會出現以下錯誤結果:
thread 1 sell ticket: 20
thread 1 sell ticket: 20
thread 2 sell ticket: 19
thread 1 sell ticket: 18
...
thread 2 sell ticket: 1
----------------------------------------------------------------------------------

 

----------------例子:事件對象------------------------------------------------

#include <windows.h><br />#include <iostream.h><br />int tickets=20;<br />HANDLE g_hEvent;<br />DWORD WINAPI Fun1Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />WaitForSingleObject(g_hEvent,INFINITE);<br />//ResetEvent(g_hEvent);<br />if (tickets>0)<br />{<br />Sleep(1);<br /> cout<<"thread 1 sell ticket: "<<tickets--<<endl;<br />SetEvent(g_hEvent);<br />}<br />else<br />{<br />SetEvent(g_hEvent);<br />break;<br />}<br />}<br />return 0;<br />}<br />DWORD WINAPI Fun2Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />WaitForSingleObject(g_hEvent,INFINITE);<br />//ResetEvent(g_hEvent);<br />if (tickets>0)<br />{<br />Sleep(1);<br /> cout<<"thread 2 sell ticket: "<<tickets--<<endl;<br />SetEvent(g_hEvent);<br />}<br />else<br />{<br />SetEvent(g_hEvent);<br />break;<br />}<br />}<br />return 0;<br />}<br />void main()<br />{<br />HANDLE hThread1;<br />HANDLE hThread2;<br />g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);<br />SetEvent(g_hEvent);<br />hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);<br />hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);<br />CloseHandle(hThread1);<br />CloseHandle(hThread2);<br />Sleep(1000);<br />CloseHandle(g_hEvent);<br />}

 

----------------例子:關鍵程式碼片段---------------------------------------------

//<QA>注釋掉兩個Mark的程式碼後,出現記憶體不能寫異常。<br />#include <windows.h><br />#include <iostream.h><br />int tickets=20;<br />CRITICAL_SECTION g_cs;<br />DWORD WINAPI Fun1Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />EnterCriticalSection(&g_cs);<br />Sleep(1); //Mark<br />if (tickets>0)<br />{<br />Sleep(1);<br /> cout<<"thread 1 sell ticket: "<<tickets--<<endl;<br />LeaveCriticalSection(&g_cs);<br />}<br />else<br />{<br />LeaveCriticalSection(&g_cs);<br />break;<br />}<br />}<br />return 0;<br />}<br />DWORD WINAPI Fun2Proc(LPVOID lpPrama)<br />{<br />while(TRUE)<br />{<br />EnterCriticalSection(&g_cs);<br />Sleep(1); //Mark<br />if (tickets>0)<br />{<br />Sleep(1);<br /> cout<<"thread 2 sell ticket: "<<tickets--<<endl;<br />LeaveCriticalSection(&g_cs);<br />}<br />else<br />{<br />LeaveCriticalSection(&g_cs);<br />break;<br />}<br />}<br />return 0;<br />}<br />void main()<br />{<br />HANDLE hThread1;<br />HANDLE hThread2;<br />hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);<br />hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);<br />CloseHandle(hThread1);<br />CloseHandle(hThread2);<br />InitializeCriticalSection(&g_cs);<br />Sleep(1000);<br />DeleteCriticalSection(&g_cs);<br />}

聯繫我們

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