阐述linux IPC(五岁以下儿童):system V共享内存
? ? ? ? system V共享內(nèi)存和posix共享內(nèi)存類(lèi)似,system V共享內(nèi)存是調(diào)用shmget函數(shù)和shamat函數(shù)。 ??
? ? ? ? shmget函數(shù)創(chuàng)建共享內(nèi)存區(qū),或者訪(fǎng)問(wèn)一個(gè)存在的內(nèi)存區(qū),類(lèi)似系統(tǒng)調(diào)用共享內(nèi)存的open和posix共享內(nèi)存shm_open函數(shù)。
shmget函數(shù)原型為:
? ? ? ? ftok函數(shù)原型為:key_t ftok(const char *pathname, int proj_id); 參數(shù)pathname為文件絕對(duì)路徑名,proj_id為一個(gè)整型標(biāo)識(shí)符。該函數(shù)將一個(gè)已存在的的路徑名和一個(gè)整型標(biāo)識(shí)符轉(zhuǎn)化成一個(gè)key_t值(返回值),稱(chēng)為IPC鍵。
? ? ? ? size:創(chuàng)建新的共享內(nèi)存大小,當(dāng)創(chuàng)建一片新的共享內(nèi)存時(shí)。該值為不為0的參數(shù)。假設(shè)是讀取一片共享內(nèi)存,該值能夠?yàn)?。
 ? ? ? ? shmflg:讀寫(xiě)權(quán)限值組合。
IPC_CREAT(創(chuàng)建新的共享內(nèi)存)或IPC_CREAT|IPC_EXCL(當(dāng)將要?jiǎng)?chuàng)建的共享內(nèi)存已經(jīng)存在時(shí),再試圖創(chuàng)建將返回EEXIST)。
事實(shí)上IPC_CREAT和IPC_EXCL的組合和open函數(shù)的O_CREAT和O_EXCL組合類(lèi)似。
 ? ? ? ? 函數(shù)返回共享內(nèi)存區(qū)的標(biāo)識(shí)。
shmxxx函數(shù)操作共享內(nèi)存將使用該函數(shù)返回值。
該函數(shù)類(lèi)似posix共享內(nèi)存shm_open函數(shù)功能。
 ? ? ? ? 當(dāng)shmget創(chuàng)建或打開(kāi)一個(gè)共享內(nèi)存區(qū)后。須要使用函數(shù)shmat來(lái)將該片共享內(nèi)存連接到當(dāng)前進(jìn)程空間中來(lái),當(dāng)某一進(jìn)程使用完共享內(nèi)存后,使用函數(shù)shmdt斷開(kāi)和共享內(nèi)存的鏈接。
? ? ? ? shmaddr: 連接到調(diào)用進(jìn)程地址空間的地址,假設(shè)該參數(shù)為NULL,系統(tǒng)選擇一個(gè)合適地址。假設(shè)shmaddr非空而且shmflg指定了選項(xiàng)SHM_RND,那么對(duì)應(yīng)的共享內(nèi)存鏈接到由shmaddr參數(shù)指定的地址向下舍入一個(gè)SHMLAB常值。假設(shè)shmaddr非空而且shmflg未指定SHM_RND,共享內(nèi)存地址鏈接到shmaddr參數(shù)指定的地址。
? ? ? ? shmflg:能夠指定SHM_RND和SHM_RDONLY(僅僅讀),假設(shè)指定SHM_RDONLY選項(xiàng)。那么調(diào)用進(jìn)程對(duì)該片共享內(nèi)存僅僅有讀權(quán)限,否則,進(jìn)程對(duì)該片內(nèi)存將有讀寫(xiě)權(quán)限。
? ? ? ? 函數(shù)shmdt不會(huì)刪除指定的共享內(nèi)存,它僅僅是斷開(kāi)和該片共享內(nèi)存的鏈接而已。當(dāng)一個(gè)進(jìn)程終止后。該進(jìn)程鏈接的共享內(nèi)存將自己主動(dòng)斷開(kāi)。
? ? ? ? shmat函數(shù)成功返回當(dāng)前進(jìn)程共享內(nèi)存地址,失敗返回(void *)-1;shmdt成功返回0。失敗返回-1;
? ? ? ? 刪除共享內(nèi)存須要函數(shù)shmctl調(diào)用IPC_RMID命令來(lái)完畢。
#include <sys/ipc.h>#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);
? ? ? ? shmid:共享內(nèi)存區(qū)標(biāo)識(shí)。
? ? ? ? cmd:對(duì)共享內(nèi)存的操作命令,命令I(lǐng)PC_RMID銷(xiāo)毀(destroy)一片共享內(nèi)存,銷(xiāo)毀之后全部shmat。shmdt,shmctl對(duì)該片內(nèi)存操作都將失效。銷(xiāo)毀該共享內(nèi)存要等到該共享內(nèi)存引用計(jì)數(shù)變?yōu)?才進(jìn)行。IPC_SET命令設(shè)置shmid_ds結(jié)構(gòu)成員;IPC_STAT返回當(dāng)前共享內(nèi)存結(jié)構(gòu)。其余命令查看man手冊(cè)。
? ? ? ? buf:為指向shmid_ds數(shù)據(jù)結(jié)構(gòu);
system V 共享內(nèi)存演示樣例:
server process:
int sln_shm_get(char *shm_file, void **mem, int mem_len) {int shmid;key_t key;if (NULL == fopen(shm_file, "w+")) {printf("fopen: %s\n", strerror(errno));return -1;}key = ftok(shm_file, 0);if (key < 0) {printf("ftok: %s\n", strerror(errno));return -1;}shmid = shmget(key, mem_len, IPC_CREAT);if (shmid < 0) {printf("shmget: %s\n", strerror(errno));return -1;}*mem = (void *)shmat(shmid, NULL, 0);if ((void *)-1 == *mem) {printf("shmat: %s\n", strerror(errno));return -1;}return shmid; }int main(int argc, const char *argv[]) {char *shm_file = NULL;char *shm_buf = NULL;int shmid;shmid = sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN);if (shmid < 0) {return -1;}snprintf(shm_buf, SHM_IPC_MAX_LEN, "Hello system V shaare memory IPC! this is write by server.");sleep(15); printf("System V server delete share memory segment!\n");//shmdt(shm_buf);shmctl(shmid, IPC_RMID, NULL); //server在15秒之后destroy該片共享內(nèi)存。此時(shí)客戶(hù)進(jìn)程將獲取不到共享內(nèi)存的內(nèi)容return 0; }
client process:
執(zhí)行時(shí),首先執(zhí)行server process,使用命令ipcs能夠查看當(dāng)前系統(tǒng)共享內(nèi)存:
# ipcs ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x0010a797 131072 root 0 4096 1 ------ Semaphore Arrays -------- key semid owner perms nsems
能夠看到存在一個(gè)共享內(nèi)存區(qū),當(dāng)中key為:0x0010a797 ,共享內(nèi)存ID為:131072?
# ./client ipc client get: Hello system V shaare memory IPC! this is write by server. #
當(dāng)server進(jìn)程destroy共享內(nèi)存之后,再反復(fù)上面步驟,
# ipcs ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status ------ Semaphore Arrays -------- key semid owner perms nsems 此時(shí)共享內(nèi)存已經(jīng)不在了,但文件依舊存在。
# ./client ipc client get: #
此時(shí)client已經(jīng)不能獲取之前共享內(nèi)存內(nèi)容了。
另外,ipcrm命令能夠在命令行上刪除指定共享內(nèi)存區(qū)。
通過(guò)讀取文件/proc/sys/kernel/shmmax能夠獲取系統(tǒng)所支持共享內(nèi)存最大值,
# cat /proc/sys/kernel/shmmax 33554432 #
能夠看到我眼下系統(tǒng)支持最大個(gè)共享內(nèi)存值為:32M。
通過(guò)上演示樣例能夠看到system V共享內(nèi)存和posix共享內(nèi)存類(lèi)似,只是posix共享內(nèi)存的大小能夠隨時(shí)通過(guò)ftruncate改變,而system V 的共享內(nèi)存大小在shmget時(shí)就已經(jīng)確定下來(lái)了。
 相同的,system V共享內(nèi)存大多數(shù)時(shí)候也須要在多進(jìn)程之間同步,system V 能夠使用自己的信號(hào)量來(lái)實(shí)現(xiàn),具體細(xì)節(jié)將在后面同步相關(guān)專(zhuān)欄具體解說(shuō)。
 本節(jié)源代碼下載:
版權(quán)聲明:本文博客原創(chuàng)文章,博客,未經(jīng)同意,不得轉(zhuǎn)載。
轉(zhuǎn)載于:https://www.cnblogs.com/mengfanrong/p/4712512.html
總結(jié)
以上是生活随笔為你收集整理的阐述linux IPC(五岁以下儿童):system V共享内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。