阿里巴巴的網(wǎng)站是自己做的嗎青島seo推廣
概念
Windows 中每個(gè)內(nèi)核對(duì)象都只是一個(gè)內(nèi)存塊,它由操作系統(tǒng)內(nèi)核分配,并只能由操作系統(tǒng)內(nèi)核進(jìn)
行訪問(wèn)
它的所有者:內(nèi)核對(duì)象的所有者是操作系統(tǒng)內(nèi)核,而非進(jìn)程,也就是說(shuō)當(dāng)進(jìn)程退出,內(nèi)核對(duì)象不一定會(huì)銷毀
法
法即規(guī)則,假設(shè)進(jìn)程A創(chuàng)建了內(nèi)核對(duì)象1,那么它的使用計(jì)數(shù)便為1,因?yàn)槌醮蝿?chuàng)建內(nèi)核對(duì)象,使用計(jì)數(shù)為 1,而如果有其他進(jìn)程訪問(wèn)內(nèi)核對(duì)象,引用計(jì)數(shù)便加1,只要引用計(jì)數(shù)不為0,內(nèi)核對(duì)象1永遠(yuǎn)不會(huì)被銷毀,即使進(jìn)程A退出了,也只會(huì)導(dǎo)致引用計(jì)數(shù)減1,只要它不為0,它就不會(huì)被銷毀
內(nèi)核對(duì)象和其他對(duì)象的區(qū)別:主要看是否有安全屬性這個(gè)參數(shù),
使用方式
通過(guò)句柄進(jìn)行操作,當(dāng)使用相關(guān)創(chuàng)建函數(shù),比如CreateEventW、CreateMutex都會(huì)返回一個(gè)句柄
表示了所創(chuàng)建的內(nèi)核對(duì)象
知識(shí)擴(kuò)展*:每個(gè)進(jìn)程中都有一個(gè)句柄表,存放了所有句柄的handle值
調(diào)用規(guī)則
hThread = CreateThread(... , &threadId);
這行代碼做了兩件事
-
調(diào)用CreateThread創(chuàng)建了一個(gè)線程對(duì)象(內(nèi)核對(duì)象)
-
hThread = CreateThread這句代碼本身也打開(kāi)(引用)了這個(gè)線程對(duì)象,將其句柄存入hThread變量
調(diào)用 API CreateThread 的時(shí)候,不僅僅是創(chuàng)建了一個(gè)內(nèi)核對(duì)象,引用計(jì)數(shù)+1,還打開(kāi)了內(nèi)核對(duì)象
+1,所以引用計(jì)數(shù)變?yōu)?2
調(diào)用 CloseHandle(hThread),即關(guān)閉hthread,然后就不能再通過(guò)hthread訪問(wèn)了,但是線程沒(méi)有關(guān)閉,也就是說(shuō)這個(gè)內(nèi)核對(duì)象的引用計(jì)數(shù)仍為1,那么線程和這個(gè)對(duì)象之間通過(guò)什么聯(lián)系呢?這個(gè)hthread已經(jīng)關(guān)閉了,他們就是通過(guò)&threadId進(jìn)行聯(lián)系。
具體解釋可以看我提的問(wèn)題
線程同步之信號(hào)量
信號(hào)量(semaphore)就相當(dāng)于停車場(chǎng)的門衛(wèi),線程好比要停的車
semaphore的組成
1.計(jì)數(shù)器 該內(nèi)核對(duì)象被使用的次數(shù)
2.最大資源數(shù),好比車位
3.當(dāng)前資源數(shù),好比沒(méi)被占用的可停車的車位
法
法即規(guī)則,如果當(dāng)前資源數(shù)大于0,那么信號(hào)量處于可觸發(fā)狀態(tài),表示有可用資源
2.如果當(dāng)前資源等于0,未觸發(fā)狀態(tài),表示無(wú)可用資源,當(dāng)前資源數(shù)不會(huì)小于0,也不會(huì)大于最大資源數(shù)
3.信號(hào)量允許多個(gè)線程共享同一份資源,而互斥量不允許,這是他們的區(qū)別,但是信號(hào)量允許的多個(gè)線程的數(shù)量是有限制的
CreateSemaphoreW (_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /安全屬性_In_ LONG lInitialCount,
/初始化時(shí),共有多少個(gè)資源是可以用的。_In_ LONG lMaximumCount, /能夠處理的最大的資源數(shù)量 _In_opt_ LPCWSTR lpName /NULL 信號(hào)量的名稱
);
WINAPI
ReleaseSemaphore (_In_ HANDLE hSemaphore, /信號(hào)量的句柄_In_ LONG lReleaseCount, /將lReleaseCount值加到信號(hào)量的當(dāng)前資源計(jì)數(shù)上面 _Out_opt_ LPLONG lpPreviousCount /當(dāng)前資源計(jì)數(shù)的原始值
);
關(guān)閉句柄
CloseHandle (_In_ _Post_ptr_invalid_ HANDLE hObject
);
線程同步之關(guān)鍵代碼段
關(guān)鍵代碼段也稱臨界區(qū),通常指多線程中訪問(wèn)同一種資源的那部分代碼,工作在用戶方式下,在代碼執(zhí)行前,它必須獨(dú)占對(duì)某些資源的訪問(wèn)權(quán),關(guān)鍵代碼段不是內(nèi)核對(duì)象,屬于用戶對(duì)象
使用步驟
初始化關(guān)鍵代碼段
調(diào)用 InitializeCriticalSection 函數(shù)初始化一個(gè)關(guān)鍵代碼段。
InitializeCriticalSection(_Out_ LPCRITICAL_SECTION lpCriticalSection
);
?首先需要構(gòu)造一個(gè) CRITICAL_SCTION 結(jié)構(gòu)體類型的對(duì)象,然后將該對(duì)象的地址傳遞給InitializeCriticalSection 函數(shù)。
進(jìn)入關(guān)鍵代碼段
VOID
WINAPI
EnterCriticalSection (_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
?獲得指定的臨界區(qū)對(duì)象的所有權(quán),該函數(shù)等待指定的臨界區(qū)對(duì)象的所有權(quán),如果該所有權(quán)賦予了調(diào)用線程,則該函數(shù)就返回;否則該函數(shù)會(huì)一直等待,從而導(dǎo)致線程等待,即阻塞在這里
退出關(guān)鍵代碼段
VOID
WINAPI
LeaveCriticalSection (_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
?釋放指定的臨界區(qū)對(duì)象的所有權(quán)。之后,其他想要獲得該臨界區(qū)對(duì)象所有權(quán)的線程就可以獲得該所有權(quán),和事件里的SetEvent差不多
WINBASEAPI
VOID
WINAPI
DeleteCriticalSection (_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
關(guān)鍵代碼段和事件對(duì)象的區(qū)別在于,執(zhí)行完線程A可以繼續(xù)執(zhí)行線程A,而在事件對(duì)象里,執(zhí)行完線程A后 就必須等待其他線程的SetEvent。內(nèi)核對(duì)象的線程同步,比如互斥量、事件對(duì)象、信號(hào)量對(duì)象不會(huì)發(fā)生死鎖 ,為什么呢?
利用內(nèi)核對(duì)象線程同步的時(shí)候,速度較慢,關(guān)鍵代碼段速度較快
內(nèi)核對(duì)象可以跨進(jìn)程,因?yàn)樗莾?nèi)核對(duì)象,而關(guān)鍵代碼段只能作用本進(jìn)程