生活随笔
收集整理的這篇文章主要介紹了
进程之间的通信方式-共享内存
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
共享內(nèi)存是被多個(gè)進(jìn)程共享的一部分物理內(nèi)存。共享內(nèi)存是進(jìn)程間共享數(shù)據(jù)的一種最快的方法,一個(gè)進(jìn)程向共享內(nèi)存區(qū)域?qū)懭肓藬?shù)據(jù),共享這個(gè)內(nèi)存區(qū)域的所有進(jìn)程就可以立刻看到其中的內(nèi)容。原理圖如下:
共享內(nèi)存的實(shí)現(xiàn)分為兩個(gè)步驟:
一、 創(chuàng)建共享內(nèi)存,使用shmget函數(shù)。
二、 映射共享內(nèi)存,將這段創(chuàng)建的共享內(nèi)存映射到具體的進(jìn)程空間去,使用shmat函數(shù)。
創(chuàng)建共享內(nèi)存
int shmget(key_t key ,int size,int shmflg)
key標(biāo)識共享內(nèi)存的鍵值:0/IPC_PRIVATE。當(dāng)key的取值為IPC_PRIVATE,則函數(shù)shmget將創(chuàng)建一塊新的共享內(nèi)存;如果key的取值為0,而參數(shù)中又設(shè)置了IPC_PRIVATE這個(gè)標(biāo)志,則同樣會創(chuàng)建一塊新的共享內(nèi)存。
返回值:如果成功,返回共享內(nèi)存表示符,如果失敗,返回-1。
映射共享內(nèi)存
int shmat(int shmid,char *shmaddr,int flag)
參數(shù):
shmid:shmget函數(shù)返回的共享存儲標(biāo)識符
flag:決定以什么樣的方式來確定映射的地址(通常為0)
返回值:
如果成功,則返回共享內(nèi)存映射到進(jìn)程中的地址;如果失敗,則返回-1。
共享內(nèi)存解除映射
當(dāng)一個(gè)進(jìn)程不再需要共享內(nèi)存時(shí),需要把它從進(jìn)程地址空間中多里。
int shmdt(char *shmaddr)
貢獻(xiàn)內(nèi)存實(shí)例如下:
實(shí)驗(yàn)要求:創(chuàng)建兩個(gè)進(jìn)程,在A進(jìn)程中創(chuàng)建一個(gè)共享內(nèi)存,并向其寫入數(shù)據(jù),通過B進(jìn)程從共享內(nèi)存中讀取數(shù)據(jù)。
chm_com.h函數(shù)
[cpp]?view plaincopy
#define?TEXT_SZ?2048?? ?? struct?shared_use_st?? {?? ????int?written_by_you;?? ????char?some_text[TEXT_SZ];?? };??
讀取進(jìn)程:
[cpp]?view plaincopy
? ? ? ? ? ? ?? #include?<unistd.h>?? #include?<stdlib.h>?? #include?<stdio.h>?? #include?<string.h>?? #include?<sys/types.h>?? #include?<sys/ipc.h>?? #include?<sys/shm.h>?? #include?"shm_com.h"?? ?? ? ? ?? int?main(void)?? {?? ????int?running=1;?? ????void?*shared_memory=(void?*)0;?? ????struct?shared_use_st?*shared_stuff;?? ????int?shmid;?? ?????? ????shmid=shmget((key_t)1234,sizeof(struct?shared_use_st),0666|IPC_CREAT);?? ????if(shmid==-1)?? ????{?? ????????fprintf(stderr,"shmget?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ?? ?????? ????shared_memory=shmat(shmid,(void?*)0,0);?? ????if(shared_memory==(void?*)-1)?? ????{?? ????????fprintf(stderr,"shmat?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ????printf("Memory?attached?at?%X\n",(int)shared_memory);?? ?? ?????? ????shared_stuff=(struct?shared_use_st?*)shared_memory;?? ?? ?????? ????shared_stuff->written_by_you=0;?? ?????? ????while(running)?? ????{?? ???????if(shared_stuff->written_by_you)?? ???????{?? ???????????printf("You?wrote:%s",shared_stuff->some_text);?? ???????????sleep(1);???? ???????????shared_stuff->written_by_you=0;?? ???????????if(strncmp(shared_stuff->some_text,"end",3)==0)?? ???????????{?? ???????????????running=0;??? ???????????}?? ???????}?? ????}?? ?????? ????if(shmdt(shared_memory)==-1)?? ????{?? ????????fprintf(stderr,"shmdt?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ???????exit(EXIT_SUCCESS);?? }??
寫入進(jìn)程:
[cpp]?view plaincopy
? ? ? ? ? ? ?? #include?<unistd.h>?? #include?<stdlib.h>?? #include?<stdio.h>?? #include?<string.h>?? #include?<sys/types.h>?? #include?<sys/ipc.h>?? #include?<sys/shm.h>?? #include?"shm_com.h"?? ?? ? ? ?? int?main(void)?? {?? ????int?running=1;?? ????void?*shared_memory=(void?*)0;?? ????struct?shared_use_st?*shared_stuff;?? ????char?buffer[BUFSIZ];?? ????int?shmid;?? ?????? ????shmid=shmget((key_t)1234,sizeof(struct?shared_use_st),0666|IPC_CREAT);?? ????if(shmid==-1)?? ????{?? ????????fprintf(stderr,"shmget?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ?? ?????? ????shared_memory=shmat(shmid,(void?*)0,0);?? ????if(shared_memory==(void?*)-1)?? ????{?? ????????fprintf(stderr,"shmat?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ????printf("Memory?attached?at?%X\n",(int)shared_memory);?? ?? ?????? ????shared_stuff=(struct?shared_use_st?*)shared_memory;?? ?????? ????while(running)?? ????{?? ????????while(shared_stuff->written_by_you==1)?? ????????{?? ????????????sleep(1);?? ????????????printf("waiting?for?client...\n");?? ????????}?? ????????printf("Ener?some?text:");?? ????????fgets(buffer,BUFSIZ,stdin);?? ????????strncpy(shared_stuff->some_text,buffer,TEXT_SZ);?? ????????shared_stuff->written_by_you=1;?? ????????if(strncmp(buffer,"end",3)==0)?? ????????{?? ????????????running=0;???? ????????}?? ????}?? ?????? ????if(shmdt(shared_memory)==-1)?? ????{?? ????????fprintf(stderr,"shmdt?failed\n");?? ????????exit(EXIT_FAILURE);?? ????}?? ????exit(EXIT_SUCCESS);?? }??
3 . 在一個(gè)終端中運(yùn)行shm1,在另一個(gè)終端中運(yùn)行shm2.當(dāng)shm1運(yùn)行起來之后,由于共享內(nèi)存中沒有數(shù)據(jù)可讀,會處于等待狀態(tài)
[root@localhost 2-4-4]# ./shm1
Memory attached at B7F9A000
/***阻塞***/
再向shm2運(yùn)行的終端輸入字符串
[root@localhost 2-4-4]# ./shm2
Memory attached at B7FD8000
Enter some text:Impossible is nothing
waiting for client。。。
waiting for client。。。
Enter some text:Anything is possible
waiting for client。。。
Ener some text:end
[root@localhost 2-4-4]#
shm1能夠逐個(gè)從共享內(nèi)存中巴他們讀出來,知道雙方暈倒字符串"end"后,兩個(gè)程序都退出。
[root@localhost 2-4-4]# ./shm1
Memory attached at B7F9A000
You write:Impossible is nothing
You write:Anything is possible
You write:end
[root@localhost 2-4-4]#
以上運(yùn)行過程中,紅色表示在終端1中運(yùn)行的結(jié)果,藍(lán)色表示在終端2里面運(yùn)行的結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的进程之间的通信方式-共享内存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。