共享内存

来源:互联网 发布:淘宝摄影棚出租 编辑:程序博客网 时间:2024/05/21 17:12

共享内存

    共享内存是被多个进程共享的一部分物理内存。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。原理图如下:

共享内存的实现分为两个步骤:

一、 创建共享内存,使用shmget函数。

二、 映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数。

创建共享内存

int shmget(key_t key ,int size,int shmflg)

key标识共享内存的键值:0/IPC_PRIVATE。当key的取值为IPC_PRIVATE,则函数shmget将创建一块新的共享内存;如果key的取值为0,而参数中又设置了IPC_PRIVATE这个标志,则同样会创建一块新的共享内存。

返回值:如果成功,返回共享内存表示符,如果失败,返回-1。

映射共享内存

int shmat(int shmid,char *shmaddr,int flag)

参数:

shmid:shmget函数返回的共享存储标识符

flag:决定以什么样的方式来确定映射的地址(通常为0)

返回值:

如果成功,则返回共享内存映射到进程中的地址;如果失败,则返回-1。

共享内存解除映射

当一个进程不再需要共享内存时,需要把它从进程地址空间中多里。

int shmdt(char *shmaddr)

贡献内存实例如下:

实验要求:创建两个进程,在A进程中创建一个共享内存,并向其写入数据,通过B进程从共享内存中读取数据。

chm_com.h函数

[cpp] view plain copy
  1. #define TEXT_SZ 2048  
  2.   
  3. struct shared_use_st  
  4. {  
  5.     int written_by_you;  
  6.     char some_text[TEXT_SZ];  
  7. };  


读取进程:

[cpp] view plain copy
  1. /********************************************************** 
  2. *实验要求:   创建两个进程,通过共享内存进行通讯。 
  3. *功能描述:   本程序申请和分配共享内存,然后轮训并读取共享中的数据,直至 
  4. *           读到“end”。 
  5. *日    期:   2010-9-17 
  6. *作    者:   国嵌 
  7. **********************************************************/  
  8. #include <unistd.h>  
  9. #include <stdlib.h>  
  10. #include <stdio.h>  
  11. #include <string.h>  
  12. #include <sys/types.h>  
  13. #include <sys/ipc.h>  
  14. #include <sys/shm.h>  
  15. #include "shm_com.h"  
  16.   
  17. /* 
  18.  * 程序入口 
  19.  * */  
  20. int main(void)  
  21. {  
  22.     int running=1;  
  23.     void *shared_memory=(void *)0;  
  24.     struct shared_use_st *shared_stuff;  
  25.     int shmid;  
  26.     /*创建共享内存*/  
  27.     shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);  
  28.     if(shmid==-1)  
  29.     {  
  30.         fprintf(stderr,"shmget failed\n");  
  31.         exit(EXIT_FAILURE);  
  32.     }  
  33.   
  34.     /*映射共享内存*/  
  35.     shared_memory=shmat(shmid,(void *)0,0);  
  36.     if(shared_memory==(void *)-1)  
  37.     {  
  38.         fprintf(stderr,"shmat failed\n");  
  39.         exit(EXIT_FAILURE);  
  40.     }  
  41.     printf("Memory attached at %X\n",(int)shared_memory);  
  42.   
  43.     /*让结构体指针指向这块共享内存*/  
  44.     shared_stuff=(struct shared_use_st *)shared_memory;  
  45.   
  46.     /*控制读写顺序*/  
  47.     shared_stuff->written_by_you=0;  
  48.     /*循环的从共享内存中读数据,直到读到“end”为止*/  
  49.     while(running)  
  50.     {  
  51.        if(shared_stuff->written_by_you)  
  52.        {  
  53.            printf("You wrote:%s",shared_stuff->some_text);  
  54.            sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写  
  55.            shared_stuff->written_by_you=0;  
  56.            if(strncmp(shared_stuff->some_text,"end",3)==0)  
  57.            {  
  58.                running=0; //结束循环  
  59.            }  
  60.        }  
  61.     }  
  62.     /*删除共享内存*/  
  63.     if(shmdt(shared_memory)==-1)  
  64.     {  
  65.         fprintf(stderr,"shmdt failed\n");  
  66.         exit(EXIT_FAILURE);  
  67.     }  
  68.        exit(EXIT_SUCCESS);  
  69. }  


写入进程:

[cpp] view plain copy
  1. /********************************************************** 
  2. *实验要求:   创建两个进程,通过共享内存进行通讯。 
  3. *功能描述:   本程序申请了上一段程序相同的共享内存块,然后循环向共享中 
  4. *           写数据,直至写入“end”。 
  5. *日    期:   2010-9-17 
  6. *作    者:   国嵌 
  7. **********************************************************/  
  8. #include <unistd.h>  
  9. #include <stdlib.h>  
  10. #include <stdio.h>  
  11. #include <string.h>  
  12. #include <sys/types.h>  
  13. #include <sys/ipc.h>  
  14. #include <sys/shm.h>  
  15. #include "shm_com.h"  
  16.   
  17. /* 
  18.  * 程序入口 
  19.  * */  
  20. int main(void)  
  21. {  
  22.     int running=1;  
  23.     void *shared_memory=(void *)0;  
  24.     struct shared_use_st *shared_stuff;  
  25.     char buffer[BUFSIZ];  
  26.     int shmid;  
  27.     /*创建共享内存*/  
  28.     shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);  
  29.     if(shmid==-1)  
  30.     {  
  31.         fprintf(stderr,"shmget failed\n");  
  32.         exit(EXIT_FAILURE);  
  33.     }  
  34.   
  35.     /*映射共享内存*/  
  36.     shared_memory=shmat(shmid,(void *)0,0);  
  37.     if(shared_memory==(void *)-1)  
  38.     {  
  39.         fprintf(stderr,"shmat failed\n");  
  40.         exit(EXIT_FAILURE);  
  41.     }  
  42.     printf("Memory attached at %X\n",(int)shared_memory);  
  43.   
  44.     /*让结构体指针指向这块共享内存*/  
  45.     shared_stuff=(struct shared_use_st *)shared_memory;  
  46.     /*循环的向共享内存中写数据,直到写入的为“end”为止*/  
  47.     while(running)  
  48.     {  
  49.         while(shared_stuff->written_by_you==1)  
  50.         {  
  51.             sleep(1);//等到读进程读完之后再写  
  52.             printf("waiting for client...\n");  
  53.         }  
  54.         printf("Ener some text:");  
  55.         fgets(buffer,BUFSIZ,stdin);  
  56.         strncpy(shared_stuff->some_text,buffer,TEXT_SZ);  
  57.         shared_stuff->written_by_you=1;  
  58.         if(strncmp(buffer,"end",3)==0)  
  59.         {  
  60.             running=0;  //结束循环  
  61.         }  
  62.     }  
  63.     /*删除共享内存*/  
  64.     if(shmdt(shared_memory)==-1)  
  65.     {  
  66.         fprintf(stderr,"shmdt failed\n");  
  67.         exit(EXIT_FAILURE);  
  68.     }  
  69.     exit(EXIT_SUCCESS);  
  70. }  

3 . 在一个终端中运行shm1,在另一个终端中运行shm2.当shm1运行起来之后,由于共享内存中没有数据可读,会处于等待状态

[root@localhost 2-4-4]# ./shm1

Memory attached at B7F9A000

/***阻塞***/

再向shm2运行的终端输入字符串

[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能够逐个从共享内存中巴他们读出来,知道双方晕倒字符串"end"后,两个程序都退出。

[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]#

以上运行过程中,红色表示在终端1中运行的结果,蓝色表示在终端2里面运行的结果。

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 三个月宝宝眼睛流泪有眼屎怎么办 小孩眼睛流泪有眼屎怎么办 宝宝上火眼睛有好多眼屎怎么办 宝宝眼睛流泪还有眼屎怎么办? 新生儿眼睛上火眼屎多怎么办 铁耳屎在最里面怎么办 婴儿鼻屎特别深怎么办 鼻子干呼吸就疼怎么办 儿童鼻子里总有好多鼻屎怎么办 小孩鼻子里有鼻屎呼吸不通怎么办 鼻子不通通气鼻屎粘在鼻子怎么办 鼻子里面干燥长鼻屎怎么办 鼻孔里干的难受怎么办 每天有很多鼻屎怎么办 鼻子里面干的疼怎么办 婴儿鼻屎堵住了怎么办 婴儿有很多鼻屎怎么办 隆鼻7天好多鼻屎怎么办 隆鼻第五天好多鼻屎怎么办 小孩鼻屎堵住了怎么办 风寒感冒流清鼻涕怎么办 流清鼻涕吐黄痰不发烧怎么办 宝宝流黄鼻涕发烧怎么办 感冒了浓鼻涕多怎么办 感冒流浓鼻涕怎么办速效办法 孩子一直流清水鼻涕怎么办 宝宝鼻子呼噜呼噜响怎么办 鼻涕往嗓子里流怎么办 咳嗽痰多鼻涕多怎么办 没感冒嗓子痰多鼻涕怎么办 孩子感冒后鼻涕特别多怎么办 经常有鼻涕怎么办才好 怀孕后鼻涕痰多怎么办 鼻炎有鼻涕痰多怎么办 宝宝咳嗽痰多鼻涕多怎么办 宝宝两岁清鼻涕咳嗽痰多怎么办 喉咙咸咸的有痰怎么办 宝宝咳嗽鼻塞喉咙有痰怎么办 绝地求生刺激战场射击键误触怎么办 在皮卡堂卡的游泳了怎么办 假如遇到老赖没能力还钱怎么办