Linux API-共享記憶體:shmget、shmat、shmdt、shmctl
阿新 • • 發佈:2021-02-17
共享記憶體特性
- 共享記憶體存在於Linux核心中,可以使資料雙向流動
- 系統核心的所有程序都可共享此記憶體空間
- 程序可直接訪問共享記憶體,通訊速度快、效率高
- 通常用訊號量來實現程序對共享記憶體同步訪問的控制
共享記憶體API
- shmget——建立/開啟共享記憶體
- shmat——將共享記憶體與當前程序相關聯
- shmdt——將當前程序與共享記憶體間脫離關聯
- shmctl——操控共享記憶體
一、shmget——建立/開啟共享記憶體
1.原函式
表頭檔案
#include <sys/ipc.h>
#include <sys/shm.h>
定義函式
int shmget(key_t key, size_t size, int shmflg);
函式說明——建立/開啟共享記憶體
key——共享記憶體名稱(ftok()函式獲取
size——開闢共享記憶體大小
shmflg——許可權標誌
返回值——成功返回共享記憶體的識別符號。錯誤返回-1
2.示例
key_t key=ftok(".",1);
int shmid=shmget(key,1024*4,IPC_CREAT|0600);//此共享記憶體的許可權為可讀可寫
二、shmat——將共享記憶體與當前程序相關聯
1.原函式
表頭檔案
#include <sys/types.h>
#include <sys/shm.h>
定義函式
void *shmat(int shmid, const void *shmaddr, int shmflg);
函式說明——將共享記憶體與當前程序相關聯
shmid——共享記憶體的識別符號(shmget的返回值)
shmaddr——使用0(核心選擇儲存地址)
shmflg —— 使用0 (記憶體空間可讀可寫)
返回值——成功返回該共享記憶體的首地址。失敗返回-1,錯誤程式碼在errno
2.示例
char *shaddr=shmat(shmid,0,0);//將共享記憶體與當前程序相關聯
三、shmdt——將當前程序與共享記憶體間脫離關聯
1.原函式
表頭檔案
#include <sys/types.h>
#include <sys/shm.h>
定義函式
int shmdt(const void *shmaddr);
函式說明——將當前程序與共享記憶體間脫離關聯
shmaddr——shmat()的返回值
返回值——成功返回0。出錯返回-1,錯誤程式碼在errno
2.示例
key_t key=ftok(".",1);
int shmid=shmget(key,1024*4,IPC_CREAT|0600);//此共享記憶體的許可權為可讀可寫
char *shaddr=shmat(shmid,0,0);//將共享記憶體與當前程序相關聯
shmdt(shaddr);//將當前程序與共享記憶體間脫離關聯
四、shmctl——操控共享記憶體
1.原函式
表頭檔案
#include <sys/ipc.h>
#include <sys/shm.h>
定義函式
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函式說明——操控共享記憶體
shmid —— shmget的返回值
cmd —— 對共享記憶體的指令
buf —— 記憶體各種資訊的結構體指標(共享記憶體模式和訪問許可權)(預設為0)
返回值——成功返回0。出錯返回-1,錯誤程式碼在errno
2.引數取值
cmd引數:
IPC_STAT:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。
IPC_SET:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值
IPC_RMID:刪除共享記憶體段
struct shmid_ds結構體預設如下:
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
3.示例
key_t key=ftok(".",1);
int shmid=shmget(key,1024*4,IPC_CREAT|0600);//此共享記憶體的許可權為可讀可寫
char *shaddr=shmat(shmid,0,0);//將共享記憶體與當前程序相關聯
shmdt(shaddr);//將當前程序與共享記憶體間脫離關聯
shmctl(shmid,IPC_RMID,0);//刪除共享記憶體
共享記憶體通訊例程
先寫後讀
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
int main()
{
key_t key;
int shmid;
char *shaddr;
key=ftok(".",'k');//鍵值獲取
shmid=shmget(key,1024*4,IPC_CREAT|0600);//此共享記憶體的許可權為可讀可寫
shaddr=shmat(shmid,0,0);//將共享記憶體與當前程序相關聯
memset(shaddr,0,strlen(shaddr));
strcpy(shaddr,"Hello");//先向shaddr記憶體寫資料
sleep(5);
printf("write succeed\n");
printf("read succeed:%s\n",shaddr);//後在shaddr記憶體讀資料
shmdt(shaddr);//將當前程序與共享記憶體間脫離關聯
shmctl(shmid,IPC_RMID,0);//刪除共享記憶體
return 0;
}
先讀後寫
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int main()
{
key_t key;
int shmid;
char *shaddr;
key=ftok(".",'k');//鍵值獲取
shmid=shmget(key,1024*4,0);//此共享記憶體的許可權為可讀可寫
shaddr=shmat(shmid,0,0);//將共享記憶體與當前程序相關聯
printf("read succeed:%s\n",shaddr);//先在shaddr記憶體讀資料
memset(shaddr,0,strlen(shaddr));
strcpy(shaddr,"World");//後向shaddr記憶體寫資料
sleep(5);
printf("write succeed\n");
shmdt(shaddr);//將當前程序與共享記憶體間脫離關聯
return 0;
}
執行結果:先執行先寫後讀,再執行先讀後寫
write succeed
read succeed:World
read succeed:Hello
write succeed
喜歡的請收藏,謝謝你。星辰~念