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

  共享内存是最快的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,表示连接操作用来只读共享内存

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的共享内存。

猜你喜欢

转载自www.cnblogs.com/wanmeishenghuo/p/9434096.html