window核心編程-核心對象線程同步

來源:互聯網
上載者:User
window核心編程-核心對象線程同步1、核心對象線程同步介紹

上一章講了關鍵字(臨界區)線程同步,使用關鍵字線程同步,我們很容易陷入死結的情形,這是因為我們無法為進入關鍵段指定一個最長等待時間。

本章將討論如何使用核心對象來對線程同步。我們也將看到,與使用者模式下的同步機制(關鍵段同步)相比,核心對象的用途要廣泛的多。實際上,核心對象唯一的缺點就是它們的效能。核心對象包括進程、線程以及作業,幾乎所有這些核心對象都可以用來進行同步。對線程同步來書,這些核心對象中的每一種要麼處於觸發狀態,要麼處於未觸發狀態。Microsoft為每種對象建立了一些規則,規定如何在這兩種狀態之間進行轉換。例如,進程核心對象在建立的時候總是處於未觸發狀態。當進程終止的時候,作業系統會自動使進程核心對象變成觸發狀態。當進程核心對象被觸發後,它將永遠保持這種狀態,再也不會變回到未觸發狀態。在進程核心對象的內部有一個布爾變數,當系統建立核心對象的時候會把這個變數的值初始化為false(未觸發)。當進程終止的時候,作業系統會自動把相應的核心對象中的這個布爾值設為true,表示該對象已經被觸發。


下邊講一些核心同步中用到的函數。
等該函數使一個線程自願進入等待狀態,直到指定的核心對象被觸發為止。

DWORD waitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);
//hObject:核心物件控點
//dwMilliseconds等待時間ms為單位,INFINITE為一直等待,只到核心對象被觸發為止。

DWORD WaitForMultipleObjects( DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds );
//waitForSingleObject和WaitForMultipleObjects相似,唯一的不同之處在於它允許調用線程同時檢查多個核心對象的觸發狀態

/*函數的傳回值告訴調用方函數為什麼它得以繼續運行。如果給bWaitAll傳的是FALSE,那麼只要任何一個對象被觸發,函數就會立即返回。這時的傳回值是WAIT_OBJECT_0和(WAIT_OBJECT_0+dwCount-1)之間的任何一個值。換句話說,如果傳回值既不是WAIT_TIMEOUT,也不是WAIT_FAILED,那麼我們應該把傳回值減去WAIT_OBJECT_0。得到的數值是我們在第二個參數中傳的控制代碼數組的一個索引,用來告訴我們被觸發的是那個對象。*/


//下面的案例代碼可以更清晰的對此進行解釋

HANDLE h[3];//我的部落格:http://blog.csdn.net/windows_nth[0] = hProcess1;h[1] = hProcess2;h[2] = hProcess3;DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);switch(dw){case WAIT_FAILED://Bad call to function (invalid handle)break;case WAIT_TIMEOUT://None of the objects became signaled within 5000 millisecondsbreak;case WAIT_OBJECT_0 + 0://h[0] signaled, hProcess1 terminatedbreak;case WAIT_OBJECT_0 + 1://h[1] signaled, hProcess2 terminatedbreak;case WAIT_OBJECT_0 + 2://h[2] signaled, hProcess3 terminatedbreak;}

2、事件核心對象

//事件包含一個使用計數(這一點和所有其他核心對象一樣),一個用來表示事件是自動重設事件還是手動重設事件的布爾值,以及另一個用來表示事件有沒有被觸發的布爾值。
//有兩種不同類型的事件對象:手動重設事件和自動重設事件。當一個手動重設事件被觸發的時候,正在等待該事件的所有線程都將變成可調度狀態,而當一個自動重設事件被觸發的時候,只有一個正在等待該事件的線程會變成可調用狀態。

//建立一個事件核心對象
HANDLE CreateEvent( 
LPSECURITY_ATTRIBUTES lpEventAttributes, //安全屬性
BOOL bManualReset, //自動重設/手動重設
BOOL bInitialState, //是否觸發

LPCSTR lpName );//事件核心對象的名字,可以為空白

//新版本

HANDLE CreateEventEx(
LPSECURITY_ATTRIBUTES psa, //安全屬性
PCTSTR pszName, //名字
DWORD dwFlags, //是否觸發

DWORD dwDesiredAccess)

//dwDesiredAccess:允許我們指定在建立事件時返回的控制代碼對事件有何種存取權限。這是一種建立事件控制代碼的新方法,它可以減少許可權,相比較而言,CreateEvent()總是被授予全部許可權。但CreateEventEx()更有用的地方在於它允許我們以減少許可權的方式來開啟一個已經存在的事件,而CreateEvent()總是要求全部許可權。


//下邊這個例子展示了如何使用事件核心對象來對線程進行同步。

//Create a global handle to a manual-reset, nonsignaled event.HANDLE g_hEvent;int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,  LPSTR lpCmdLine, int nShowCmd ){//Create the manual-reset, nonsignaled eventg_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//Spawn 3 new threadsHANDLE hThread[3];DWORD dwThread;hThread[0] = _beginthread(NULL, 0, wordCount, NULL, 0, &dwThread);hThread[1] = _beginthread(NULL, 0, SpellCheck, NULL, 0, &dwThread);hThread[2] = _beginthread(NULL, 0, GrammarCheck, NULL, 0, &dwThread);OpenFileAndReadContentsIntoMemory(...);//allow all 3 threads to access the memorySetEvent(g_hEvent);}DWORD WINAPI wordCount(PVOID pvParam){//Wait until the file's data is in memorywaitForSingleObject(g_hEvent, INFINITE);//access the memory block.return 0;}DWORD WINAPI SpellCheck(PVOID pvParam){//Wait until the file's data is in memorywaitForSingleObject(g_hEvent, INFINITE);//access the memory block.return 0;}DWORD WINAPI GrammarCheck(PVOID pvParam){//Wait until the file's data is in memorywaitForSingleObject(g_hEvent, INFINITE);//access the memory block.return 0;}

下邊是我自己寫的一個案例片段,很簡單

CString strName = _T("");UINT CBcgTestDlg::ThreadWorkFunc(LPVOID lPvoid){for (int n = 0; n < 10000; n++){strName = _T("http://blog.csdn.net/windows_nt");strName = strName + _T("\n");TRACE(strName);}return 0;}void CBcgTestDlg::OnOK() {CWinThread* pThread = NULL;for (int n = 0; n < 10000; ++n){if (pThread){WaitForSingleObject(pThread->m_hThread, INFINITE);delete pThread;}pThread = AfxBeginThread(ThreadWorkFunc, NULL, 0, CREATE_SUSPENDED, NULL);if (pThread){pThread->m_bAutoDelete = FALSE;pThread->ResumeThread();}}}

注意線程函數可以為類函數,但必須是靜態函數

聯繫我們

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