資源描述:
《linux進(jìn)程間通信 共享內(nèi)存》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Linux進(jìn)程間通信共享內(nèi)存共享內(nèi)存(SharedMemory)共享內(nèi)存區(qū)域是被多個進(jìn)程共享的一部分物理內(nèi)存。如果多個進(jìn)程都把該內(nèi)存區(qū)域映射到自己的虛擬地址空間,則這些進(jìn)程就都可以直接訪問該共享內(nèi)存區(qū)域,從而可以通過該區(qū)域進(jìn)行通信。共享內(nèi)存是進(jìn)程間共享數(shù)據(jù)的一種最快的方法,一個進(jìn)程向共享內(nèi)存區(qū)域?qū)懭肓藬?shù)據(jù),共享這個內(nèi)存區(qū)域的所有進(jìn)程就可以立刻看到其中的內(nèi)容。這塊共享虛擬內(nèi)存的頁面,出現(xiàn)在每一個共享該頁面的進(jìn)程的頁表中。但是它不需要在所有進(jìn)程的虛擬內(nèi)存中都有相同的虛擬地址。圖共享內(nèi)存映射圖象所有的SystemVIPC對象一樣,對于共享內(nèi)存對象的訪問由ke
2、y控制,并要進(jìn)行訪問權(quán)限檢查。內(nèi)存共享之后,對進(jìn)程如何使用這塊內(nèi)存就不再做檢查。它們必須依賴于其它機(jī)制,比如SystemV的信號燈來同步對于共享內(nèi)存區(qū)域的訪問。每一個新創(chuàng)建的共享內(nèi)存對象都用一個shmid_kernel數(shù)據(jù)結(jié)構(gòu)來表達(dá)。系統(tǒng)中所有的shmid_kernel數(shù)據(jù)結(jié)構(gòu)都保存在shm_segs向量表中,該向量表的每一個元素都是一個指向shmid_kernel數(shù)據(jù)結(jié)構(gòu)的指針。shm_segs向量表的定義如下:structshmid_kernel*shm_segs[SHMMNI];SHMMNI為128,表示系統(tǒng)中最多可以有128個共享內(nèi)存對象。數(shù)據(jù)
3、結(jié)構(gòu)shmid_kernel的定義如下:structshmid_kernel{structshmid_dsu;/*thefollowingareprivate*/unsignedlongshm_npages;/*sizeofsegment(pages)*/unsignedlong*shm_pages;/*arrayofptrstoframes-SHMMAX*/structvm_area_struct*attaches;/*descriptorsforattaches*/};其中:shm_pages是該共享內(nèi)存對象的頁表,每個共享內(nèi)存對象一個,它描述了如
4、何把該共享內(nèi)存區(qū)域映射到進(jìn)程的地址空間的信息。shm_npages是該共享內(nèi)存區(qū)域的大小,以頁為單位。shmid_ds是一個數(shù)據(jù)結(jié)構(gòu),它描述了這個共享內(nèi)存區(qū)的認(rèn)證信息,字節(jié)大小,最后一次粘附時間、分離時間、改變時間,創(chuàng)建該共享區(qū)域的進(jìn)程,最后一次對它操作的進(jìn)程,當(dāng)前有多少個進(jìn)程在使用它等信息。其定義如下:structshmid_ds{structipc_permshm_perm;/*operationperms*/intshm_segsz;/*sizeofsegment(bytes)*/__kernel_time_tshm_atime;/*lastat
5、tachtime*/__kernel_time_tshm_dtime;/*lastdetachtime*/__kernel_time_tshm_ctime;/*lastchangetime*/__kernel_ipc_pid_tshm_cpid;/*pidofcreator*/__kernel_ipc_pid_tshm_lpid;/*pidoflastoperator*/unsignedshortshm_nattch;/*no.ofcurrentattaches*/unsignedshortshm_unused;/*compatibility*/voi
6、d*shm_unused2;/*ditto-usedbyDIPC*/void*shm_unused3;/*unused*/};attaches描述被共享的物理內(nèi)存對象所映射的各進(jìn)程的虛擬內(nèi)存區(qū)域。每一個希望共享這塊內(nèi)存的進(jìn)程都必須通過系統(tǒng)調(diào)用將其粘附(attach)到它的虛擬內(nèi)存中。這一過程將為該進(jìn)程創(chuàng)建了一個新的描述這塊共享內(nèi)存的vm_area_struct數(shù)據(jù)結(jié)構(gòu)。進(jìn)程可以選擇共享內(nèi)存在它的虛擬地址空間的位置,也可以讓Linux為它選擇一塊足夠的空閑區(qū)域。這個新的vm_area_struct結(jié)構(gòu)除了要連接到進(jìn)程的內(nèi)存結(jié)構(gòu)mm中以外,還被連接到共享內(nèi)
7、存數(shù)據(jù)結(jié)構(gòu)shmid_kernel的一個鏈表中,該結(jié)構(gòu)中的attaches指針指向該鏈表。vm_area_struct數(shù)據(jù)結(jié)構(gòu)中專門提供了兩個指針:vm_next_shared和vm_prev_shared,用于連接該共享區(qū)域在使用它的各進(jìn)程中所對應(yīng)的vm_area_struct數(shù)據(jù)結(jié)構(gòu)。其實,虛擬內(nèi)存并沒有在粘附的時候創(chuàng)建,而要等到第一個進(jìn)程試圖訪問它的時候才創(chuàng)建。圖SystemVIPC機(jī)制-共享內(nèi)存Linux為共享內(nèi)存提供了四種操作。1.共享內(nèi)存對象的創(chuàng)建或獲得。與其它兩種IPC機(jī)制一樣,進(jìn)程在使用共享內(nèi)存區(qū)域以前,必須通過系統(tǒng)調(diào)用sys_ipc(
8、call值為SHMGET)創(chuàng)建一個鍵值為key的共享內(nèi)存對象,或獲得已經(jīng)存在的鍵值為key的某