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

    一、什么是共享内存

    不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

     特点:

    1. 共享内存在各种进程间通信方式中具有最高的效率。访问共享内存区域和访问进程独有的内存区域一样快,并不需要通过系统调用或者其它需要切入内核的过程来完成。同时它也避免了对数据的各种不必要的复制。

    2. 共享内存并未提供同步机制,需要其他机制来同步对共享内存的访问,例如信号量

    二、相关函数

    它们声明在头文件 sys/shm.h中。

    1. shmget:创建共享内存

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

    第一个参数是内核中唯一的key,可以用ftok函数生成,hmget函数成功时返回一个与key相关的共享内存标识符(非负整数),用于后续的操作都是用那个返回值了。

    2. shmat:将一个共享内存段映射到调用进程的数据段中

    第一次创建完共享内存时,它还不能被任何进程访问,shmat函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。它的原型如下:

    void *shmat(int shm_id, const void *shm_addr, int shmflg);
    第一个参数,shm_id是由shmget函数返回的共享内存标识。
    第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
    第三个参数,shm_flg是一组标志位,通常为0。
    调用成功时返回一个指向共享内存第一个字节的指针
    3. shmd函数
    将共享内存从当前进程中分离,注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。
    int shmdt(const void *shmaddr);

    4. shmctl

    用来控制共享内存,例如, IPC_RMID:删除共享内存段

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/shm.h>
    #include <sys/ipc.h>
    #include <unistd.h>
    using namespace std;
    
    int main()
    {
      char *shmaddr;
      char *shmaddread;
      char str[]="Hello, I am a processing. 
    ";
      int shmid;
    
      key_t key = ftok(".",1);
      pid_t pid1 = fork();
      if(pid1 == -1){
        cout << "Fork error. " << endl;
        exit(1);
      }
      else if(pid1 == 0){
        //子进程1
        shmid = shmget(key,1024,IPC_CREAT | 0600);
        shmaddr = (char*)shmat(shmid, NULL, 0);
                   strcpy(shmaddr, str);
        cout << "[Writer] write: " << shmaddr << endl;
        shmdt(shmaddr);
      }
      else
      {
        //父进程
        pid_t pid2 = fork();
        if(pid2 == -1){
          cout << "Fork error. " << endl;
          exit(1);
        }
        else if(pid2 == 0){
          //子进程2
          sleep(2);
          shmid = shmget(key,1024,IPC_CREAT | 0600);
          shmaddread = (char*)shmat(shmid, NULL, 0);        
          cout << "[Reader] read: " << shmaddread << endl;
          shmdt(shmaddread);
        }
      }
      sleep(3);
      return 0;
    }

    参考链接:

    1. https://blog.csdn.net/ljianhui/article/details/10253345

    2. https://blog.ailemon.me/2018/03/19/the-theory-and-implemention-on-five-ways-for-communication-between-processings/

  • 相关阅读:
    【剑指offer】面试题35:第一个只出现一次的字符
    【剑指offer】面试题34:丑数
    【剑指offer】面试题33:把数组排成最小的数
    【剑指offer】面试题32:从1到n整数中1出现的次数
    【剑指offer】面试题31:连续子数组的最大和
    【剑指offer】面试题30:最小的 k 个数
    【剑指offer】面试题29:数组中出现次数超过一半的数字
    【剑指offer】面试题28:字符串的排列
    【剑指offer】面试题27:二叉搜索树与双向链表
    【剑指offer】面试题26:复杂链表的复制
  • 原文地址:https://www.cnblogs.com/lfri/p/12697043.html
Copyright © 2011-2022 走看看