轉載地址:http://blog.csdn.net/yeyuangen/article/details/37657937
前面我們已經說過進程間的通信有好幾種方式,其實現在我們講的這種動態鏈接庫也是進程間的通信方式之一。
不管是windows還是Linux操作系統其實所有的操作系統的內涵知識都是一樣的。
動態鏈接庫是windows操作系統的基礎,其中windows API基本上都是以動態鏈接庫的形式來提供的,通常來說動態鏈接庫是不能夠直接運行,也不能直接接收消息的,他們是一些獨立的文件(后綴名一般為.dll,當然還有其它的一些后綴名也是可以的),其中包含能被可執行程序或其它DLL調用來完成某項工作的函數,也就是說動態鏈接庫也就是由一些函數組成而已。並且只有在其它模塊調用動態鏈接庫中的函數時,動態鏈接庫才發揮作用,在實際的編程中,通常可以完成某種功能的函數放在一個動態鏈接庫中,然后提供給其它函數調用。當這個訪問了的動態鏈接庫的進程被加載時,系統會為這個進程分配4GB的私有地址空間(如果是32位機的話),然后系統就會分析這個可執行模塊,找到這個可執行模塊中將所要調用的DLL,然后系統就負責搜索這些DLL找到這些DLL后便將這些DLL加載到內存中,並為他們分配虛擬內存空間,最后將DLL的頁面映射到調用進程的地址空間匯總,DLL的虛擬內存有代碼頁和數據頁,他們被分別映射到進程A的代碼頁面和數據頁面,如果這時進程B也啟動了,並且進程B也許要訪問該DLL,這時,只需要將該DLL在虛擬內存中的代碼頁面和數據頁面映射到第二個進程的地址空間即可。這也表明了在內存中,只需要存在一份DLL的代碼和數據。
多個進程共享 DLL 的同一份代碼,很明顯這樣做可以節省內存空間的。
但是在 Windows 下(Linux中也是一樣的),由於系統會為每一個進程分配 4GB 的私有地址空間,
而 DLL 中的代碼和數據也只是映射到了這個私有地址空間中,所以這些應用程序之間還是不能夠相互影響的,
也就是說多個應用程序雖然是可以共享同一個 DLL 中的相同的代碼的,
但是 DLL 為每一個進程保存的數據都是不相同的,
並且每一個進程都為 DLL 使用的全部數據分配了自己的地址空間,
舉個最簡單的例子,我的 DLL 中有一個函數為 int Add(int num1 , int num2),
這個函數的作用是實現 num1 和 num2 相加並返回相加后的結果。
然后我有一個 進程 A 使用了這個 DLL ,並且其調用了函數 Add(10, 20),
然后我還有一個 進程 B 其也使用了這個 DLL ,並且其調用了函數 Add(30, 40),
那么對於 進程 A 中的數據 10 和 20 其實是保存在 進程 A 的私有地址空間中的,
而對於 進程 B 中的數據 30 和 40 則是保存在 進程 B 的私有地址空間中的,
上面這個簡單的例子表明如果單單用這種簡單的使用動態鏈接庫的方式是不能夠實現進程之間的通信的。
如果想利用動態鏈接庫來實現進程間的通信的話,那么有一種方案可以試一試,
即從系統為動態鏈接庫分配的那一塊內存(系統需要將動態鏈接庫加載到內存中)下手,
由於在內存中,動態鏈接庫其實只存在一份,
其被所有需要調用該動態鏈接庫中的函數的模塊或者簡單說是可執行程序所共享,
既然是共享的話,如果我在系統給動態鏈接庫分配的這塊內存中保存數據,
那豈不是可以被所有訪問該動態鏈接庫的可執行程序所獲取或者說設置。
這樣的話,我就可以使用 進程 A 來設置好這個共享內存中的數據,
然后 進程 B 就可以讀取這個共享內存中的數據了,這不是也可以實現進程間的通信嘛,
這樣看來的話,其思路其實和使用剪貼板是一模一樣的了。
也是采用一塊兩個進程共享的內存來作為存放數據的中介。
