zoukankan      html  css  js  c++  java
  • Linux进程间通信之共享内存

    一,共享内存
      内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存。
      映射物理内存叫挂接,用完以后解除映射叫脱接

    1,共享内存的特点:

      优点:是最快的IPC。
      缺点:要编程者自己实现对共享内存互斥访问。如何实现?

    2,编程模型:具体函数的用法可以用man手册查看(强力推荐)

    进程A: writeshm.c
         1) 获得key, ftok()
         2) 使用key来创建一个共享内存 shmget()
         3) 映射共享内存(得到虚拟地址), shmat()
         4) 使用共享内存, 往共享内存中写入数据
         5) 解除映射 shmdt()
         6) 如果共享内存不再使用,可以使用shmctl()销毁共享内存

    进程B: readshm.c     

      1) 获得key, ftok()     

      2) 使用key来获得一个共享内存 shmget()     

      3) 映射共享内存(得到虚拟地址), shmat()     

      4) 使用共享内存, 读取共享内存中的数据     

      5) 解除映射 shmdt()     

    3,实例

    进程A:

    // writeshm.c
    
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/shm.h>
    
    int main()
    {
        // 生成一个key
        key_t key = ftok("./", 66);
    
        // 创建共享内存,返回一个id
        int shmid = shmget(key, 8, IPC_CREAT|0666|IPC_EXCL);
        if(-1 == shmid)
        {
            perror("shmget failed");
            exit(1);
        }
    
        // 映射共享内存,得到虚拟地址
        void *p = shmat(shmid, 0, 0);
        if((void*)-1 == p)
        {
            perror("shmat failed");
            exit(2);
        }
    
        // 写共享内存
        int *pp = p;
        *pp = 0x12345678;
        *(pp + 1) = 0xffffffff;
    
        // 解除映射
        if(-1 == shmdt(p))
        {
            perror("shmdt failed");
            exit(3);
        }
        printf("解除映射成功,点击回车销毁共享内存
    ");
        getchar();
    
        // 销毁共享内存
        if(-1 == shmctl(shmid, IPC_RMID, NULL))
        {
            perror("shmctl failed");
            exit(4);
        }
    
        return 0;
    }


    进程B:

    // readshm.c
    
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/shm.h>
    
    int main()
    {
        // 生成一个key
        key_t key = ftok("./", 66);
    
        // 获取共享内存,返回一个id
        int shmid = shmget(key, 0, 0);
        if(-1 == shmid)
        {
            perror("shmget failed");
            exit(1);
        }
    
        // 映射共享内存,得到虚拟地址
        void *p = shmat(shmid, 0, 0);
        if((void*)-1 == p)
        {
            perror("shmat failed");
            exit(2);
        }
    
        // 读共享内存
        int x = *(int *)p;
        int y = *((int *)p + 1);
        printf("从共享内存中都取了:0x%x 和 0x%x 
    ", x, y);
    
        // 解除映射
        if(-1 == shmdt(p))
        {
            perror("shmdt failed");
            exit(3);
        }
    
        return 0;
    }

     运行结果:

    writeshma:

    readshma:

  • 相关阅读:
    java web分享ppt大纲 -- servlet容器简介
    Docker入门二
    Docker入门
    自动化运维
    堡垒机
    代码管理平台
    NoSQL(四)
    NoSQL(三)
    NoSQL(二)
    CentOS添加新网卡network-scripts目录下找不到网卡配置文件
  • 原文地址:https://www.cnblogs.com/xcywt/p/5128430.html
Copyright © 2011-2022 走看看