码迷,mamicode.com
首页 > 系统相关 > 详细

11.1 进程间通信--共享内存

时间:2018-08-07 00:38:52      阅读:303      评论:0      收藏:0      [点我收藏+]

标签:技术   errno   原型   内存映射   只读   执行   数加   操作   ipcs   

  共享内存是最快的IPC形式,一旦这样的内存映射到共享它的进程的地址空间,这些进程间的数据传递不再涉及到内核,也就是说进程不再通过执行进入内核的系统调用来传递彼此的数据。写共享内存要加锁。常和信号量在一起使用。消息队列和管道读写数据都是要进入内核的。

示意图如下:

技术分享图片

 

传递数据的示意图如下:

技术分享图片

 

共享内存的数据结构及基本API:

技术分享图片

 

shmget函数:

  原型:int shmget(key_t  key,  size_t size,  int  shmflg)

  功能:用来创建共享内存

  参数:

    key:这个共享内存段的名字

    size:共享内存的大小

    shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的

  返回值:

    成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

shmat函数:

  原型:void*  shmat(int  shmid,  const  void*  shmaddr,  int  shmflg)

  功能:将共享内存段连接到进程地址空间

  参数:

    shmid:共享内存标识

    shmaddr:指定连接的地址

    shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY

  返回值:成功返回一个指针,指向共享内存第一个字节;失败返回-1

shmat函数(续):

  shmaddr为NULL,内核自动选择一个地址

  shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连续地址

  shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr  %  SHMLBA)

  shmflg为SHM_RDONLY,表示连接操作用来只读共享内存

shmdt函数:

  原型:int shmdt(const  void*  shmaddr)

  功能:将共享内存段与当前进程脱离

  参数:

    shmaddr:由shmat所返回的指针

  返回值:成功返回0,失败返回-1

  注意:将共享内存与当前进程脱离不等于删除共享内存段

shmctl函数:

  原型:int  shmctl(int shmid,  int  cmd,  struct  shmid_ds *buf)

  功能:用于控制共享内存

  参数:

    shmid:由shmget返回的共享内存标识码

    cmd:将要采取的动作,有三个可取值

    buf:指向一个保持着共享内存的模式状态和访问权限的数据结构

  返回值:成功返回0,失败返回-1

cmd的三个可选值如下:

技术分享图片

shmget示例程序如下:

 

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/shm.h>

typedef struct 
{
    char name[10];
    int age;
}Teacher;

int main()
{
    int ret = 0;
    
    ret = shmget(0x2222, sizeof(Teacher), 0666);
    
    if( -1 == ret )
    {
        if(errno == ENOENT)
        {
            printf("check if shm exist \n");
        }
        
        perror("shmget error");
        exit(0);
    }    
    
    printf("shmget success \n");
    
    return 0;
}

 

最后一个参数填写0666,相当于打开共享内存,不存在的话会报错,执行结果如下:

技术分享图片

 

给最后一个参数加上创建属性,如下:

 1 #include <sys/types.h>
 2 #include <unistd.h>
 3 #include <stdio.h>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <errno.h>
 7 #include <sys/msg.h>
 8 #include <sys/ipc.h>
 9 #include <sys/shm.h>
10 
11 typedef struct 
12 {
13     char name[10];
14     int age;
15 }Teacher;
16 
17 int main()
18 {
19     int ret = 0;
20     
21     ret = shmget(0x2222, sizeof(Teacher), 0666 | IPC_CREAT);
22     
23     if( -1 == ret )
24     {
25         if(errno == ENOENT)
26         {
27             printf("check if shm exist \n");
28         }
29         
30         perror("shmget error");
31         exit(0);
32     }    
33     
34     printf("shmget success \n");
35     
36     return 0;
37 }

再次执行结果如下:

技术分享图片

 

使用ipcs查看系统中的共享内存,如下:

技术分享图片

 

可以看到最后一个key值为0x2222的共享内存。

 shmat将数据写入共享内存,如下所示:

 1 #include <sys/types.h>
 2 #include <unistd.h>
 3 #include <stdio.h>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <errno.h>
 7 #include <sys/msg.h>
 8 #include <sys/ipc.h>
 9 #include <sys/shm.h>
10 
11 typedef struct 
12 {
13     char name[10];
14     int age;
15 }Teacher;
16 
17 int main()
18 {
19     int ret = 0;
20     
21     ret = shmget(0x2222, sizeof(Teacher), 0666 | IPC_CREAT);
22     
23     if( -1 == ret )
24     {
25         if(errno == ENOENT)
26         {
27             printf("check if shm exist \n");
28         }
29         
30         perror("shmget error");
31         exit(0);
32     }    
33     
34     Teacher t1 = {"zhang", 26};
35     
36     Teacher *t = shmat(ret, NULL, 0);
37     
38     memcpy(t, &t1, sizeof(t1));
39     
40     return 0;
41 }

 

11.1 进程间通信--共享内存

标签:技术   errno   原型   内存映射   只读   执行   数加   操作   ipcs   

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9434096.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!