嵌入式 Linux程序間通訊(八) 共享記憶體

2021-12-30 04:25:42 字數 3978 閱讀 8709

嵌入式 linux程序間通訊(八)——共享記憶體

一、共享記憶體

共享記憶體允許兩個或更多程序共享給定的記憶體區,資料不需要在不同程序間進行複製,是最快的程序間通訊方式。使用共享記憶體唯一需要注意的是多個程序之間對給定儲存區的同步訪問,但共享記憶體本身沒有提供同步機制,通常使用訊號量來實現對共享記憶體訪問的同步。

共享記憶體程式設計流程:建立共享記憶體、對映共享記憶體、使用共享記憶體、撤銷對映操作、刪除共享記憶體

1、建立共享記憶體

#include

#include

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

key:非0整數

size:以位元組為單位指定需要共享的記憶體容量

shm***:許可權標誌,可以與ipc_creat做或操作

shmget函式成功時返回乙個與key相關的共享記憶體識別符號(非負整數)。呼叫失敗返回-1.

2、對映共享記憶體

#include

#include

void *shmat(int shmid, const void *shmaddr, int shm***);

shm_id是由shmget函式返回的共享記憶體標識。

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

shm_***是一組標誌位,通常為0。

呼叫成功時返回乙個指向共享記憶體第乙個位元組的指標,如果呼叫失敗返回-1。

3、使用共享記憶體

可以使用不帶快取的io函式對共享記憶體進行能操作

4、撤銷對映共享記憶體操作

#include

#include

int shmdt(const void *shmaddr);

將共享記憶體從當前程序中分離,shmaddr是shmat函式返回的位址指標,呼叫成功時返回0,失敗時返回-1。

5、刪除共享記憶體

#include

#include

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

shm_id是shmget函式返回的共享記憶體識別符號。

command是要採取的操作,有三種操作:

ipc_stat:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。

ipc_set:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值

ipc_rmid:刪除共享記憶體段

buf是乙個結構指標,它指向共享記憶體模式和訪問許可權的結構。

shmid_ds結構至少包括以下成員:

struct shmid_ds

uid_t shm_perm.uid;

uid_t shm_perm.gid;

mode_t shm_perm.mode;

二、共享記憶體程式設計例項

使用共享記憶體進行程序間通訊程式例項:

shmdata.**件(定義共享記憶體的資料結構):

#ifndef shmdata_h

#define shmdata_h

#define data_size 1024

typedef struct shm

int flag;//非0,可讀,0,可寫

unsigned char data[data_size];//資料

}share_memory;

#endif

shmread.c:

#include

#include

#include

#include

#include

#include

#include

#include "shmdata.h"

int main(int argc, char **ar**)

int shmid;

void *shm = null;

share_memory *shmdata;

key_t key = ftok("./shmread.c", 'k');

shmid = shmget(key, sizeof(share_memory), 0666|ipc_creat);

if(shmid == -1)

fprintf(stderr, "shmget failed.\n");

exit(-1);

shm = shmat(shmid, 0, 0);

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

fprintf(stderr, "shmat failed.\n");

exit(-1);

fprintf(stdout, "sharememory at 0x%x\n", shm);

shmdata = (share_memory *)shm;

shmdata->flag = 1;

int read = 1;

while(read)

if(shmdata->flag)

printf("share memory data:%s\n", shmdata->data);

shmdata->flag = 0;

else

printf("waiting...\n");

sleep(1);

if(shmdt(shm) == -1)

fprintf(stderr, "shmdt failed.\n");

exit(-1);

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

fprintf(stderr, "shmdt failed.\n");

exit(-1);

return 0;

shmwrite.c:

#include

#include

#include

#include

#include

#include

#include

#include "shmdata.h"

int main(int argc, char **ar**)

int shmid;

void *shm = null;

share_memory * shmdata;

key_t key = ftok("./shmread.c", 'k');

shmid = shmget(key, sizeof(share_memory), 0666|ipc_creat);

char buffer[128] = "hello wolrd";

if(shmid == -1)

fprintf(stderr, "shmget failed.\n");

exit(-1);

shm = shmat(shmid, 0, 0);

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

fprintf(stderr, "shmat failed.\n");

exit(-1);

fprintf(stdout, "sharememory at 0x%x\n", shm);

shmdata = (share_memory *)shm;

int read = 1;

while(read)

if(shmdata->flag == 0)

printf("writing...\n");

strncpy(shmdata->data, buffer,sizeof(buffer));

shmdata->flag = 1;

else

printf("waiting...\n");

sleep(1);

if(shmdt(shm) == -1)

fprintf(stderr, "shmdt failed.\n");

exit(-1);

return 0;

嵌入式Linux程序 程序間通訊

最常用的無名管道,有名管道,訊息佇列,訊號,訊號量,共享記憶體等程序間的通訊方式。其實後面網路通訊套位元組 socket的方式也可以歸為程序通行。include include include include 程序讀函式 void read data int 程序寫函式 void write dat...

嵌入式 Linux程序間通訊(八) 共享記憶體

共享記憶體允許兩個或更多程序共享給定的記憶體區,資料不需要在不同程序間進行複製,是最快的程序間通訊方式。使用共享記憶體唯一需要注意的是多個程序之間對給定儲存區的同步訪問,但共享記憶體本身沒有提供同步機制,通常使用訊號量來實現對共享記憶體訪問的同步。共享記憶體程式設計流程 建立共享記憶體 對映共享記憶...

嵌入式綜合複習(程序間通訊的方式)

1.管道pipe 管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。2.命名管道fifo 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。3.訊息佇列messagequeue 訊息佇列是由訊息的鍊錶,存放在核心中並由...