核心對象的建立和使用

來源:互聯網
上載者:User

 

1、進程核心物件控點表

2、建立與關閉核心對象

3、進程間核心物件控點的共用

 

 

1、進程核心物件控點表

當一個進程初始化時,系統會為它分配一張核心物件控點表。這個表只用於管理核心物件控點。GDI和使用者物件不會影響到這張表。表中的每一項有4個域。  即控制代碼ID,對象記憶體位址,訪問屏蔽位,標誌位。

 

當一個進程初始化時,控制代碼表為空白。 現在假設你調用CreateFile函數建立一個檔案對象,核心首先會尋找當前進程中的控制代碼表,將一個空的表項取出來,並分配一個核心對象,將該對象的地址寫入第二個域(即,對象記憶體位址),然後訪問屏蔽設定為完全訪問,相應的標誌位也會被設定。用於核心對象建立時返回與進程相關的控制代碼,而這些控制代碼可以在同一個進程中被其所有線程使用。該控制代碼是一個非透明值,有可能返回的是控制代碼表中的索引,也有可能是一個其它的值。但這個控制代碼的確是可以與這個核心對象相關聯。

 

2、建立與關閉核心對象

如果建立核心對象失敗,那返回的控制代碼通常為NULL,但也有可能是INVALID_HANDLE_VALUE,例如CreateFile函數。當查看一個函數的傳回值時,應該特別小心。

 

無論你是怎麼建立核心對象,都應該調用CloseHandle將其釋放。核心會檢測這個對象的引用計數,當發現他的引用計數為0的時候,便會將其釋放。 並且,如果一個進程中,如果調用了CloseHandle,則這個HANDLE對此進程則會變成無效,而對於其它使用這個核心的進程來說,並沒有影響。

 

3、進程間核心物件控點的共用

當一個進程建立出一個核心對象時,這個對象就與此進程相關聯。但是,並不是所有情況都是如此,許多時候,我們需要多個進程之間共用核心對象。共用一個核心物件控點的方法大概有三種。 1、通過繼承共用,2、通過有名核心對象共用。3、通過控制代碼拷貝共用。

註:共用的是核心對象的控制代碼,核心對象屬於核心,無法共用。

 

通過繼承共用則要求共用的進程間是父子關係。 如一個進程中調用CreateFile建立了一個檔案對象。如果我們想要這個對象的控制代碼在這個進程的子進程中被使用。則我們在建立這個對象時,對SECURYTY_ATTRIBUTES結構中的bInheritHande設定為TRUE。 這樣這個控制代碼就能夠被子進程共用。 而我們在建立子進程時,需在調用CreateProcess時將其參數bInheritHandles傳遞為TRUE,標誌著他需要繼承父進程的控制代碼。

值得注意的是,繼承控制代碼相當於是對父進程中控制代碼的拷貝,當一個進程被建立時,如果指定為需要對父進程中的控制代碼進行繼承,則系統會尋找其父進程中的控制代碼表,找到可以繼承的控制代碼,並將其整個表項複製到子進程的控制代碼表中。核心對象的引用計數相應增加1。 因此,如果一個子進程被建立後。父進程又建立了一個可以繼承的物件控點。但這個控制代碼不會被子進程繼承。

另外一個問題就是,子進程無法知道自己擁有了該控制代碼的使用權,此時就需要通過一些手法來讓子進程知道。最常用的便是通過參數傳遞。將控制代碼值通過pCommandLine傳遞給子進程,子進程解析後使用。也可以通過訊息或是環境變數的方式通知。。

 

通過有名對象進行物件控點共用是最簡單的方式,像事件,訊號量,互斥變數等都支援有名建立。如建立CreateMutex的時候,只需為其最後一個參數傳遞一個0結尾的字串,便可以標誌這個變數。需要注意的是,這個名字很有可能衝突,不同種內的核心對象共同使用一個名字池,如果已經有這個名字,並且先前使用此名字的核心對象也是一個Mutex,則當調用GetLastError()時,會返回ERROR_ALREADY_EXISTS。 系統將直接返回其控制代碼,並將其引用計數加1。否則返回NULL,表示建立失敗。

 

由於這個特性,我們可以使用它來強制你的程式只能開一個執行個體。代碼如下

 

 #include<windows.h><br />#include<tchar.h><br />int _tmain() </p><p>{ </p><p> HANDLE hMutex = CreateMutex(NULL,TRUE,”MyMutex”); </p><p> if(GetLastError() == ERROR_ALREADY_EXISTS) </p><p> { </p><p> MessageBox(TEXT(“程式已經有一個執行個體在執行”),TEXT(“友情提示”),MB_OK);<br /> CloseHandle(hMutex);</p><p> return 0;<br /> } </p><p> //做你程式應該做的事<br /> CloseHandle(hMutex);<br /> return 0; </p><p>} </p><p>本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/wqjqepr/archive/2010/06/26/5695561.aspx

 

最後一個共用變數的方式就是採用DuplicateHandle進行拷貝,具體用法參照MSDN即可。

 

對象的控制代碼是一個非透明的值,在不同的場合,會有不同的控制代碼與同一個核心對象對應。標誌著不同的許可權,不同的環境。 因此用到的時候要十分小心。並且應該注意控制代碼的關閉,以防止運行過程中內在泄漏。同時應該注意控制代碼值的有效性,不要使用一個已經釋放了的控制代碼值。

聯繫我們

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