Linux系統程式設計--共享記憶體
阿新 • • 發佈:2021-01-13
共享記憶體
介紹共享記憶體之前我們先看一下鍵值。
什麼是鍵值?
鍵值:
就是保證程序之間開啟的通訊的介質是同一個
linux的鍵值:
以某個數值開啟一個檔案所產生出來的
ID是固定的
比如說一個檔案在/home/lyx/test/1.c
特定的函式:獲取鍵值的函式
XXX(/home/lyx/test/1.c);
開啟這個檔案,返回的ID是一個定值不管你用哪個程序不管何時刻,你在整個Linux下開啟這個檔案返回的這個ID都是一定的
保證唯一性:
只要有唯一性
就可以利用這個唯一性
來建立訊息佇列、
兩個程序都用這個ID建立/開啟訊息佇列
很明顯,兩個程序必然是訪問的一個訊息佇列
函式功能:保證程序開啟的共享記憶體、訊息佇列、訊號量集是同一個
函式標頭檔案:
#include <sys/types.h>
#include <sys/ipc.h>
函式原型:
key_t ftok(const char *pathname, int proj_id);
函式引數:
char *pathname:你要參考的檔案
proj_id :你要參考的ID號(0~255)
函式返回值:
返回你需要的鍵值
失敗返回 -1
//獲取一個參考檔案的固定的ID
//ID固定產生唯一性
//產生唯一性
//就可以以此為媒介作為建立/開啟某個通訊介質的條件
接下來我們看一下關於共享記憶體的函式:
函式功能:建立一個共享記憶體
函式標頭檔案:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函式原型:int shmget(key_t key, size_t size, int shmflg);
函式引數:
key:鍵值->以ftok獲得
0 -> 僅用於父子間程序
size: 指定的空間大小位元組
shmflg:跟許可權碼非常相似
IPC_CREAT|0777
//沒有就建立
函式返回值:
成功的返回建立共享記憶體的ID
失敗返回 -1
/***************************************/
共享記憶體的對映:
函式功能:往程序中對映一個特定的共享記憶體
函式標頭檔案:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函式原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);
函式引數:
shmid:共享ID號
shmaddr :對映的地址
你可以指定一個地址
你也可以讓系統指定
0
shmflg:0: 可讀可寫
SHM_RDONLY:共享記憶體只讀
函式返回值:
返回這片空間對映的地址
共享記憶體:預設是沒有阻塞的
相當於一個特別陣列
這個陣列大家都可以訪問
/***********************************/
函式功能:解除對映一個已經對映的共享記憶體
函式標頭檔案:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函式原型:
int shmdt(const void *shmaddr);
函式引數:
shmaddr:就是已經被對映的地址
函式返回:
0 成功
-1 失敗
/*****************************/
函式功能:控制一個共享記憶體
函式標頭檔案:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函式原型:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函式引數:
shmid:共享記憶體的ID號
cmd : 操作
獲取屬性---IPC_STAT
設定共享記憶體--IPC_SET
刪除共享記憶體(最常用)-IPC_RMID
shmid_ds *buf:
如果獲取屬性
那麼他就把屬性存到結構體
如果設定:
操作結構體
如果刪除:
直接填寫NULL
演示程式碼
在父程序裡面建立共享記憶體並且開啟,然後向共享記憶體中寫入一句話,子程序從共享記憶體中讀出這句話
共享記憶體:
共享單車
公共廁所
多個人共用
多個程序可以共用
記憶體:
一個儲存空間
牽扯到空間的東西一般都跟地址有關
共享記憶體就是一片地址
想要用共享記憶體:
*建立共享記憶體
*對映共享記憶體空間
*解除對映
*刪除共享空間
超級全域性變數(記憶體):
所有程序都可以呼叫
都可以改變
void Test_shm(void)
{
pid_t pd=0;
int shm_id;
char * shm_addr =NULL;
pd = fork();
if(pd > 0)//父程序
{
shm_id = shmget(ftok("./TEST/main.c",0),32,IPC_CREAT|0664);//建立
shm_addr = (char *)shmat(shm_id,(void *)0,0);//對映 可讀可寫
strcpy(shm_addr,"i am father\n");
shmdt(shm_addr);//解除對映共享記憶體
}else//子程序
{
sleep(1);
shm_id = shmget(ftok("./TEST/main.c",0),32,IPC_CREAT|0664);/開啟
shm_addr = (char *)shmat(shm_id,(void *)0,0);//對映 可讀可寫
printf("son: %s\n",shm_addr);
shmdt(shm_addr);//解除對映共享記憶體
shmctl(shm_id,IPC_RMID,NULL);//刪除共享記憶體
}
}
演示結果: