【校招 --阶段一 系统编程】system V共享内存
一、什么是system V共享內(nèi)存
共享內(nèi)存區(qū)是最快的IPC形式。一旦這樣的內(nèi)存映射到共享它的進(jìn)程的地址空間,這些進(jìn)程間數(shù)據(jù)傳遞不再涉及到
內(nèi)核,換句話說(shuō)是進(jìn)程不再通過(guò)執(zhí)行進(jìn)入內(nèi)核的系統(tǒng)調(diào)用來(lái)傳遞彼此的數(shù)據(jù)
當(dāng)兩個(gè)進(jìn)程在物理內(nèi)存中開(kāi)辟同一塊i空間,并且映射到兩個(gè)進(jìn)程的地址空間的共享內(nèi)存中,兩個(gè)進(jìn)程就能建立通信
當(dāng)一個(gè)進(jìn)程往里面寫(xiě)入數(shù)據(jù),那一個(gè)進(jìn)程直接就能看到。中間沒(méi)有緩沖區(qū)的作用。
創(chuàng)建共享內(nèi)存時(shí)操作系統(tǒng)提供的
共享內(nèi)存函數(shù)
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok( const char * pathname , int proj_id );
參數(shù):
pathname 就時(shí)你指定的文件名(該文件必須是存在而且可以訪問(wèn)的),id是子序號(hào),雖 然為int,但是只有8個(gè)比特被使用(0-255)。
返回值: 成功時(shí)候返回key_t 類型的key值,失敗返回-1
函數(shù)ftok把一個(gè)已存在的路徑名和一個(gè)整數(shù)標(biāo)識(shí)得轉(zhuǎn)換成一個(gè)key_t值
IPC(共享內(nèi)存)資源隨內(nèi)核,如果不釋放,就一直存在。
功能:用來(lái)創(chuàng)建共享內(nèi)存
原型
int shmget(key_t key, size_t size, int shmflg);
參數(shù)
key:這個(gè)共享內(nèi)存段名字
size:共享內(nèi)存大小
shmflg:由九個(gè)權(quán)限標(biāo)志構(gòu)成,它們的用法和創(chuàng)建文件時(shí)使用的mode模式標(biāo)志是一樣的
返回值:成功返回一個(gè)非負(fù)整數(shù),即該共享內(nèi)存段的標(biāo)識(shí)碼(使用戶層面的,而key值時(shí)操作系統(tǒng)層面依賴標(biāo)識(shí)共享內(nèi)存的);失敗返回-1
shmflg主要和一些標(biāo)志有關(guān)。其中有效的包括IPC_CREAT和IPC_EXCL,它們的功能與open()的O_CREAT和O_EXCL相當(dāng)。
IPC_CREAT 如果共享內(nèi)存不存在,則創(chuàng)建一個(gè)共享內(nèi)存,否則打開(kāi)操作。
IPC_EXCL 只有在共享內(nèi)存不存在的時(shí)候,新的共享內(nèi)存才建立,否則就產(chǎn)生錯(cuò)誤。
如果單獨(dú)使用IPC_CREAT ,shmget()函數(shù)要么返回一個(gè)已經(jīng)存在的共享內(nèi)存的操作符 ,要么返回一個(gè)新建的共享內(nèi)存的標(biāo)識(shí)符 。
如果將 IPC_CREAT和IPC_EXCL標(biāo)志一起使用,shmget()將返回一個(gè)新建的共享內(nèi)存的標(biāo)識(shí)符;如果該共享內(nèi)存已存在,或者返回-1
功能:用于控制共享內(nèi)存
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
參數(shù)
shmid:由shmget返回的共享內(nèi)存標(biāo)識(shí)碼
cmd:將要采取的動(dòng)作(有三個(gè)可取值)
buf:指向一個(gè)保存著共享內(nèi)存的模式狀態(tài)和訪問(wèn)權(quán)限的數(shù)據(jù)結(jié)構(gòu),一般為NULL
返回值:成功返回0;失敗返回-1
功能:將共享內(nèi)存段連接到進(jìn)程地址空間
原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
參數(shù)
shmid: 共享內(nèi)存標(biāo)識(shí)
shmaddr:指定連接的地址
shmflg:它的兩個(gè)可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一個(gè)指針,指向共享內(nèi)存第一個(gè)節(jié);失敗返回-1
說(shuō)明:
shmaddr為NULL,核心自動(dòng)選擇一個(gè)地址
shmaddr不為NULL且shmflg無(wú)SHM_RND標(biāo)記,則以shmaddr為連接地址。
shmaddr不為NULL且shmflg設(shè)置了SHM_RND標(biāo)記,則連接的地址會(huì)自動(dòng)向下調(diào)整為SHMLBA的整數(shù)倍。公式:shmaddr -
(shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示連接操作用來(lái)只讀共享內(nèi)存
共享內(nèi)存底層不提供任何同步互斥的機(jī)制
#include<iostream> #include <sys/types.h> #include <sys/ipc.h> #include<unistd.h> #include<stdlib.h> #include<sys/shm.h> using namespace std; int main(){ key_t k=ftok("./",0x666666); cout<<"k"<<k<<endl; int shat=shmget(k,4096,IPC_CREAT|IPC_EXCL|0666);//創(chuàng)建共享內(nèi)存 if(shat<0){cout<<"share 創(chuàng)建失敗!"<<endl; return 1; }//jianl //建立宿舍關(guān)系 char *str=(char*)shmat(shat,NULL,0); while(1){ sleep(1); cout<<str<<endl; } shmdt(str); shmat(shat,IPC_RMID,NULL);//刪除共享內(nèi)存 return 0; } #include<iostream> #include <sys/types.h> #include <sys/ipc.h> #include<unistd.h> #include<stdlib.h> #include<sys/shm.h> using namespace std; int main(){ key_t k=ftok("./",0x666666); cout<<"k"<<k<<endl; int shat=shmget(k,4096,IPC_CREAT|IPC_EXCL|0666);//創(chuàng)建共享內(nèi)存 if(shat<0){cout<<"share 創(chuàng)建失敗!"<<endl; return 1; } //jianl //建立宿舍關(guān)系 char *str=(char*)shmat(shat,NULL,0); while(1){ sleep(1); cout<<str<<endl; } shmdt(str); shmat(shat,IPC_RMID,NULL);//刪除共享內(nèi)存 return 0; } ipcrm -m 688145 #刪除shm ipc資源,注意,不是必須通過(guò)手動(dòng)來(lái)刪除,這里只為演示相關(guān)指令,刪除IPC資源是進(jìn) 程該做的事情共享內(nèi)存沒(méi)有進(jìn)行同步與互斥!
總結(jié)
以上是生活随笔為你收集整理的【校招 --阶段一 系统编程】system V共享内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Firefox 扩展“此组件无法安装,因
- 下一篇: java信息管理系统总结_java实现科