共享內(nèi)存方式:從物理內(nèi)存里面拿出來一部分作為多個進程共享。
共享內(nèi)存是進程間共享數(shù)據(jù)的一種最快的方法,一個進程向共享內(nèi)存區(qū)域?qū)懭霐?shù)據(jù),共享這個內(nèi)存的所有進程都可以立即看到其中內(nèi)容。
共享內(nèi)存實現(xiàn)步驟:
一、創(chuàng)建共享內(nèi)存,使用shmget函數(shù)。
二、映射共享內(nèi)存,將這段創(chuàng)建的共享內(nèi)存映射到具體的進程空間去,使用shmat函數(shù)。
創(chuàng)建共享內(nèi)存shmget:
intshmget(key_t key, size_t size, int shmflg)
功能:得到一個共享內(nèi)存標識符或創(chuàng)建一個共享內(nèi)存對象并返回共享內(nèi)存標識符。
key: 0(IPC_PRIVATE)會建立共享內(nèi)存對象
size:大于0的整數(shù),新建共享內(nèi)存的大小,以字節(jié)為單位。只獲取共享內(nèi)存時,指定為0.
shmflg:
0表示取共享內(nèi)存標識符,如不存在則函數(shù)會報錯;
IPC_CREAT,如果內(nèi)核中不存在鍵值與key相等的共享內(nèi)存時,則創(chuàng)建一個共享內(nèi)存;如果存在這樣的共享內(nèi)存則返回共享內(nèi)存的標識符;
IPC_CREAT|IPC_EXCL: 如果內(nèi)核中不存在鍵值與key相等的共享內(nèi)存,則新建一個消息隊列;如果存在這樣的共享內(nèi)存則報錯;
函數(shù)返回值:成功則返回內(nèi)存的標識符;出錯則返回-1,錯誤原因存在于error中
映射共享內(nèi)存到調(diào)用進程的地址空間shmat:
void*shmat(int shmid, const void *shmaddr, int shmflg)
msqid:共享內(nèi)存標識符
shmaddr:指定共享內(nèi)存出現(xiàn)在進程內(nèi)存地址的什么位置,直接指定為NULL讓內(nèi)核自己決定一個合適的地址位置。
shmflg: SHM_RDONLY 只讀模式,其他為讀寫模式
函數(shù)返回值:成功則返回附加好的共享內(nèi)存地址;出錯返回-1,錯誤原因存在于error中
斷開共享內(nèi)存連接shmdt:
intshmdt(const void *shmaddr)
功能:傳入shmaddr,連接共享的內(nèi)存起始地址;斷開成功則返回0,出錯則返回-1,錯誤原因存在于error中。
父子進程間通訊實例:
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv){
if(argc< 2){ //需要輸入共享的數(shù)據(jù)
printf("pleaseinput the shared data.n");
exit(-1);
}
intshmid;
shmid= shmget(0,1024,IPC_CREAT);
if(shmid== -1){ // 申請共享內(nèi)存失敗
printf("createshare memory failed.n");
exit(-1);
}
if(fork()){ // 父進程之中
char*p_shmaddr;
p_shmaddr= shmat(shmid, NULL, 0); // 映射到父進程之中的一個地址
memset(p_shmaddr,0, 1024); // 初始化共享內(nèi)存
strcpy(p_shmaddr,argv[1]); // 拷貝共享數(shù)據(jù)到共享內(nèi)存
wait(NULL); //等待子進程結(jié)束
exit(0);
}
else{
sleep(2); //等待父進程寫入數(shù)據(jù)
char*c_shmaddr;
c_shmaddr= shmat(shmid,NULL,0); // 映射到子進程之中一個地址,具體由kernel 指配
printf("theshare data is: %sn", c_shmaddr); //子進程輸出共享的數(shù)據(jù)