博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2.共享内存
阅读量:5313 次
发布时间:2019-06-14

本文共 4632 字,大约阅读时间需要 15 分钟。

一、概念  

共享内存:允许在系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存
                  是通信速度最快的一种IPC。
实现机制:一个进程在系统中申请开辟一块共享内存空间,然后使用这个共享内存空间的各个进程分别打开这个共享内存空间,
                 并将这个
内存空间映射到
自己的进程空间上,这样各个进程就可以共同使用这个共享内存空间,就如同使用自己进程
                 地址空间的内存一样,达到对内存的读写操作。  
共享内存相关函数:
  头文件: #include <sys/ipc.h> #include <sys/shm.h>

   int shmget(key_t key, size_t size, int shmflg);        //1.创建或获取共享内存

   void *shmat(int shmid,const void* shmaddr,int shmflg);      //2.进程链接共享内存

   int shmdt(const void* shmaddr);            //3.共享内存与当前进程脱离开

   int shmctl(int shmid, int cmd, struct shmid_ds *buf);            //4.共享内存控制函数

二、函数参数介绍

  1.shmget函数 :创建或获取共享内存

          int  shmget(key_t key,size_t size, int shmflg);
     key: 创建或获取共享内存段的键值
          size: 共享的内存空间
          shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样
          如果共享内存创建成功,shmget将返回一个非负整数,即该段共享内存的标识码;如果失败,则返回“-1”
 
  2.shmmat函数 :内存段刚创建,任何进程都不能访问该内存段。只有当内存空间映射到进程空间中,该进程
          才能访问共享内存。(建立地址映射,进程连接)
     void* shmat(int shm_id, const void *shm_addr, int shmflg);
          shm_id: shmget返回的共享内存标识码
          shm_addr:把共享内存连接到当前进程去的时候准备放置它的那个地址
          注:  1.shmaddr为0,核心自动选择一个地址(一般自动设置)
                   2.shmaddr不为0且shmflg无SHM_RND标记,则以shmaddr为连接地址。
          shmflg是一组按位OR(或)在一起的标志。它的两个可能取值是SHM_RND和SHM_RDONLY
       调用成功,返回指针,指针指向共享内存的第一个字节;失败,则返回“-1”
      其中: 
          1.在fork() 后,子进程继承已连接的共享内存
                        2.在exec后,已连接的共享内存会自动脱离(detach)
                        3.在结束进程后,已连接的共享内存会自动脱离(detach)  
 

  3.shmdt函数 :共享内存与当前进程脱离开

        int  shmdt(const void *shm_addr);
      shm_addr: 由shmat返回的地址指针
     操作成功,返回“0”,失败则返回“-1”
     注:脱离共享内存并不等于删除它,只是当前进程不能再继续访问它而已。

  4.shmctl函数 :共享内存控制函数

     int  shmctl(int shm_id,int command, struct shmid_ds *buf);

     shm_id: 由shmget返回的共享内存标识码
     command:将要采取的动作(有三个可取值)
                      
     
    buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
    操作成功,返回0,失败则返回-1
 

三、代码实例

创建共享内存,并不同进程对创建的共享内存读写操作,最后删除该共享内存。

1.创建共享内存: shmget.c文件

1 #include "stu.h" 2 #include
3 #include
4 #include
5 #include
6 7 int main() 8 { 9 int shmid = shmget((key_t)0x1001, sizeof(stu_t)*10, IPC_CREAT | IPC_EXCL | 0666);10 if(shmid == -1)11 {12 perror("shmget");13 exit(EXIT_FAILURE);14 }15 printf("shared memory created success, shmid = %d", shmid);16 return 0;17 }
View Code

2.往共享内存写数据  shmput.c文件

1 #include "stu.h" 2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 9 /******** 共享内存链接 ***********10 *1.获取shmid11 *2.连接共享内存12 *3.封装数据结构13 *4.写数据14 ***********************************/15 int main(int argc, char* argv[])16 {17 //1.获取shmid18 int shmid = shmget((key_t)0x1001, 10, 0);19 if(shmid == -1)20 {21 perror("shmget");22 exit(EXIT_FAILURE);23 }24 //2.连接共享内存25 void *pShm = shmat(shmid, 0, 0);26 if(pShm == (void*)-1)27 {28 perror("shmat");29 exit(EXIT_FAILURE);30 }31 //3.封装数据结构32 stu_t aStu = { 1001, "Tom"};33 //4.写数据34 memcpy(pShm, &aStu, sizeof(stu_t));35 //5.用完了就要断开连接36 if(shmdt(pShm)!= 0)37 {38 perror("shmdt");39 exit(EXIT_FAILURE);40 }41 return 0;42 }
View Code

3.从共享内存读数据 shmread.c文件

1 #include "stu.h" 2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 9 /******** 共享内存链接 ***********10 *1.获取shmid11 *2.连接共享内存12 *3.封装数据结构13 *4.写数据14 ***********************************/15 16 int main(int argc, char* argv[])17 {18 //1.获取shmid19 int shmid = shmget((key_t)0x1001, 10, 0);20 if(shmid == -1)21 {22 perror("shmget");23 exit(EXIT_FAILURE);24 }25 //2.连接共享内存26 void *pShm = shmat(shmid, 0, 0);27 if(pShm == (void*)-1)28 {29 perror("shmat");30 exit(EXIT_FAILURE);31 }32 //3.封装数据结构33 stu_t aStu = { 0};34 //4.写数据35 memcpy(&aStu, pShm, sizeof(stu_t));36 printf("get shmid = %d, name = %s\n", aStu.id, aStu.name);37 //5.用完了就要断开连接38 if(shmdt(pShm)!= 0)39 {40 perror("shmdt");41 exit(EXIT_FAILURE);42 }43 return 0;44 }
View Code

4.删除共享内存 shmctl.c文件

1 #include "stu.h" 2 #include
3 #include
4 #include
5 #include
6 7 int main() 8 { 9 int shmid = shmget((key_t)0x1001, 10 , 0);10 if(shmid == -1)11 {12 perror("shmget");13 exit(EXIT_FAILURE);14 }15 if(shmctl(shmid, IPC_RMID, NULL) == -1)16 {17 perror("shmctl");18 exit(EXIT_FAILURE);19 }20 return 0;21 }
View Code

5.公有文件: stu.h

1 #ifndef _STU_H 2 #define _STU_H 3  4 typedef struct student_s 5 { 6     int id; 7     char name[32]; 8 }stu_t; 9 10 #endif
View Code

 

Linux下运行图:

                               

 

 

转载于:https://www.cnblogs.com/Dana-gx/p/9735683.html

你可能感兴趣的文章
JS基础学习3
查看>>
Tennis Championship
查看>>
SQL
查看>>
JavaScript基础-var
查看>>
javascript 进阶篇1 正则表达式,cookie管理,userData
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
用WebClinet实现SharePoint上文档库中文件的上传与下载
查看>>
Silverlight和javascript的相互调用
查看>>
SQL Server 2005 Express 附加数据库只读 解决方案
查看>>
opencv中的Bayes分类器应用实例
查看>>
大数据学习
查看>>
[BZOJ2982]combination
查看>>
简单工厂模式
查看>>
Delphi7编译的程序自动中Win32.Induc.a病毒的解决办法
查看>>
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>
Python中替换元素
查看>>
关于双核心:也许你不知道的五件事
查看>>