Linux 程序間通訊 共享記憶體

2021-09-25 10:46:14 字數 3315 閱讀 9282

共享記憶體:

共享記憶體,顧名思義就是允許兩個不相關的程序訪問同乙個邏輯記憶體,共享記憶體是兩個正在執行的程序之間共享和傳遞資料的一種非常有效的方式。不同程序之間共享的記憶體通常為同一段物理記憶體。程序可以將同一段物理記憶體連線到他們自己的位址空間中,所有的程序都可以訪問共享記憶體中的位址。如果某個程序向共享記憶體寫入資料,所做的改動將立即影響到可以訪問同一段共享記憶體的任何其他程序。但是他不提供任何同步功能,需要我們用訊號量實現

共享記憶體的系統呼叫以及標頭檔案:

#include

#include

#include

int shmget(key_t key, size_t size, int shm***);

成功返回共享記憶體識別符號,出錯返回-1

功能:建立共享記憶體

第乙個引數key是長整型(唯一非零),系統建立ipc通訊 ( 訊息佇列、 訊號量和 共享記憶體) 時必須指定乙個id值。通常情況下,該id值通過ftok函式得到,由核心變成識別符號,要想讓兩個程序看到同乙個訊號集,只需設定key值不變就可以。

第二個引數size指定共享記憶體的大小,它的值一般為一頁大小的整數倍(未到一頁,作業系統向上對齊到一頁,但是使用者實際能使用只有自己所申請的大小)。 ----》shell命令:getconf page_size可以檢視當前系統頁的大小,在應用層可以使用getpagesize()函式獲取,核心層直接使用page_size這個巨集

第三個引數shm***是一組標誌,建立乙個新的共享記憶體,將shm*** 設定了ipc_creat標誌後,共享記憶體存在就開啟。而ipc_creat | ipc_excl則可以建立乙個新的,唯一的共享記憶體,如果共享記憶體已存在,返回乙個錯誤。一般我們會還或上乙個檔案許可權

int shmctl(int shm_id, int cmd, struct shmid_ds *buf);

成功返回0,出錯返回-1

功能:操作共享記憶體

(1)第乙個引數,shm_id是shmget函式返回的共享記憶體識別符號。

(2)第二個引數,cmd是要採取的操作,它可以取下面的三個值 :    

ipc_stat:得到共享記憶體的狀態,並把共享記憶體的shmid_ds結構體複製到buf中。

ipc_set:把buf中所指的shmid_ds結構中的uid、gid、mode等複製到共享記憶體的shmid_ds結構體重  

ipc_rmid:刪除共享記憶體段

(3)第三個引數,buf是乙個結構指標,它指向共享記憶體模式和訪問許可權的結構。 shmid_ds結構至少包括以下成員 

struct shmid_ds 

;void *shmat(int shm_id, const void *shm_addr, int shm***);

成功返回指向共享儲存段的指標,出錯返回-1 

功能:建立共享儲存段之後,將程序連線到它的位址空間

(1)第乙個引數,shm_id是由shmget函式返回的共享記憶體標識。

(2)第二個引數,shm_addr指定共享記憶體連線到當前程序中的位址位置,通常為空,表示讓系統來選擇共享記憶體的位址。

(3)第三個引數,shm_***是一組標誌位,通常為0,可以取如下值

shm_rnd:表示第二個引數指定的位址應被向下取整至記憶體頁大小的整數倍

shm_rdonly:表示要鏈結的共享記憶體段是唯讀的

int shmdt(const void *shmaddr);

成功返回0,出錯返回-1

功能:將共享記憶體從當前程序中分離

第乙個引數shmaddr是以前呼叫shmat時的返回值

例子shmdata.h

#ifndef _shmdata_h_header

#define _shmdata_h_header

#define text_sz 2048

struct shared_use_st

;#endif

shmread.c

#include #include #include #include #include "shmdata.h"

int main()

//將共享記憶體連線到當前程序的位址空間

shm = shmat(shmid, 0, 0);

if(shm == (void*)-1)

printf("\nmemory attached at %x\n", (int)shm); //設定共享記憶體

shared = (struct shared_use_st*)shm;

shared->written = 0;

while(running)//讀取共享記憶體中的資料

else//有其他程序在寫資料,不能讀取資料

sleep(1);

} //把共享記憶體從當前程序中分離

if(shmdt(shm) == -1)

//刪除共享記憶體

if(shmctl(shmid, ipc_rmid, 0) == -1)

exit(exit_success);

}

shmwrite.c

#include #include #include #include #include #include "shmdata.h"

int main()

//將共享記憶體連線到當前程序的位址空間

shm = shmat(shmid, (void*)0, 0);

if(shm == (void*)-1)

printf("memory attached at %x\n", (int)shm); //設定共享記憶體

shared = (struct shared_use_st*)shm;

while(running)//向共享記憶體中寫資料

//向共享記憶體中寫入資料

printf("enter some text: ");

fgets(buffer, bufsiz, stdin);

strncpy(shared->text, buffer, text_sz); //寫完資料,設定written使共享記憶體段可讀

shared->written = 1; //輸入了end,退出迴圈(程式)

if(strncmp(buffer, "end", 3) == 0)

running = 0;

} //把共享記憶體從當前程序中分離

if(shmdt(shm) == -1)

sleep(2);

exit(exit_success);

}

Linux程序間通訊 共享記憶體

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

Linux程序間共享記憶體通訊

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

Linux程序間通訊 共享記憶體

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