Linux (程序間通訊)共享記憶體剖析

2021-10-10 06:01:10 字數 2807 閱讀 6750

在linux中,每個程序都有屬於自己的程序控制塊(pcb)和位址空間(addr space),並且都有乙個與之對應的頁表,負責將程序的虛擬位址與實體地址進行對映,通過記憶體管理單元(mmu)進行管理。兩個不同的虛擬位址通過頁表對映到物理空間的同一區域,它們所指向的這塊區域即共享記憶體。

;key:共享識別符號,標識系統的唯一ipc資源。

size:需要申請共享記憶體的大小。在作業系統中,申請記憶體的最小單位為頁,一頁是4k位元組,為了避免記憶體碎片,我們一般申請的記憶體大小為頁的整數倍。

shm***:如果要建立新的共享記憶體,需要使用ipc_creat,ipc_excl,如果是已經存在的,可以使用ipc_creat或直接傳0。

返回值:成功時返回乙個新建或已經存在的的共享記憶體的操作控制代碼,失敗返回-1並設定錯誤碼。

1 #include

2 #include

3 #include

4 #define key 0x89898989

5int

main()

614//15

return0;

1617

}

檢視共享記憶體資訊:

;shmid:共享記憶體操作控制代碼。

shm***:shm_rdonly位,則以唯讀方式連線此段,否則以讀寫方式連線此段。

將共享記憶體附加到test.c檔案,作為輸入檔案,通過指標lp將「linux」傳入共享記憶體中去

1 #include

2 #include

3 #include

4 #include

56 #define key 0x8888888878

intmain()

917//18

void

* lp=

shmat

(shmid,

null,0

);19printf

("%p\n",(

char

*)lp);20

strcpy((

char

*)lp,

"linux");

21return0;

2223

}

將共享記憶體附加到read.c,作為讀端,將「linux」從共享記憶體中讀出

1 #include

2 #include

3 #include

4 #include

5 #define key 0x88888888

6int

main()

715//16

void

* lp=

shmat

(shmid,

null,0

);17printf

("%p\n",(

char

*)lp);18

printf

("%s\n"

,lp);19

20return0;

2122

}

執行結果:

**注意:**與管道不同的是,共享記憶體是訪問,之中的值並不會被拷走!!!

int

shmdt

(const

void

*shmaddr)

;

分離之前附加了兩個程序:

將read.c加上分離語句:

shmdt(lp);
分離之後只剩乙個程序:

;buf:共享記憶體結構體:

注意:刪除共享記憶體,當使用shmctl或者使用ipcrm,刪除共享記憶體之後,共享記憶體就實際被釋放掉了,當共享記憶體被釋放掉之後,共享記憶體的識別符號會被設定成為0x00000000,表示其他程序不能通過之前的識別符號找到該共享記憶體,並且共享記憶體的狀態會被設定成為dest(destroy),但是還是有程序在附加著共享記憶體,當前描述共享記憶體的結構體並沒有被釋放,直到當前共享記憶體的附加程序數量為0的時候才會被釋放掉。

Linux程序間通訊 共享記憶體

共享記憶體是執行在同一臺機器上的程序間通訊最快的方式,因為資料不需要在不同的程序間複製。通常由乙個程序建立一塊共享記憶體區,其餘程序對這塊記憶體區進行讀寫。共享記憶體往往與其它通訊機制,如訊號量結合使用,來達到程序間的同步及互斥。首先要用的函式是shmget,它獲得乙個共享儲存識別符號。i nclu...

Linux程序間共享記憶體通訊

使用共享記憶體基本分四個步驟 獲得共享記憶體 shmget 對映共享記憶體shmat 解除對映shmdt 刪除共享記憶體shmctl 於是自己在網上找來了乙個例子看了下,並且用虛擬機器單獨跑了下共享記憶體的經典例程看了下,才知道了自己的問題出現 了 發現有時候只要自己親自將程式一步一步的去測,才知道...

Linux程序間通訊 共享記憶體

之前提到了程序間通訊的管道,訊息佇列,訊號量,然後其中訊號量是pv操作,操控的是乙個共享資源。在我們提到的ipc模組中,訊息佇列針對的是資料單元的資訊傳送,管道不屬於system v ipc的部分,所以按照乙個作業系統的整體來說,他應該也有著乙個關於位元組流的訊息傳輸,並且要比之前都要快,還要跟我們...