zoukankan      html  css  js  c++  java
  • System V共享内存

    1. 概述

    System V共享内存在概念上类似于Posix共享内存,代之以调用shm_Open后调用mmap的是,先调用shmget,再调用shmat。
    对于每个System V共享内存,内核都维护如下的信息结构,它定义在sys/shm.h头文件中,其中带注释的是我们需要关注的成员。

    struct shmid_ds
    {
        struct ipc_perm  shm_perm;
        size_t           shm_segsz;  //共享内存区大小
        pid_t            shm_lpid;
        pid_t            shm_cpid;
        shmatt_t         shm_nattch;
        shmat_t          shm_cnattch;
        time_t           shm_atime;
        time_t           shm_dtime;
        time_t           shm_ctime;
    };
    

    2. System V共享内存API

    shmget

    shmget用于创建一个新的共享内存或打开一个已存在的共享内存。

    //成功返回共享内存标识符,
    int shmget(key_t key, size_t size, int oflag);
    
    • 参数size是共享内存区大小,其余两个参数含义及用法和System V信号量一样
    • 当实际操作为创建新的共享内存时,该内存区size个字节均被初始化为0
    • 当实际操作为打开已有共享内存时,size可设为0,oflag设为需要的读写权限

    shmat

    shmat用于把shmget创建或打开的共享内存连接到调用进程的地址空间。

    //成功返回映射区起始地址,失败返回-1
    void *shmat(int shmid, const void *shmaddr, int flag);
    
    • shmid是shmget返回的标识符
    • shmaddr推荐设为NULL,表示由系统决定映射区起始地址
    • flag一般设为0,因为只要调用进程具有共享内存的读写权限,那么映射区内存就也可以读写
    • flag也可以设为SHM_RDONLY限定只读访问

    shmdt

    shmdt删除由shmat建立的连接。

    //成功返回0,失败返回-1
    int shmdt(const void *shmaddr);
    

    shmctl

    shmctl用于对共享内存的各种控制操作。

    //成功返回0,失败返回-1
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    

    cmd可使用的命令有三个:

    • IPC_RMID:从系统中删除共享内存,此时buf参数设为NULL即可
    • IPC_STAT:通过buf返回共享内存对应的shmid_ds结构,一般用此命令获取共享内存区大小
    • IPC_SET:通过buf设置共享内存对应shmid_ds结构中的shm_perm.uid、shm_perm.gid和shm_perm.mode

    3. 简单的程序

    代码实现

    common.h

    #ifndef _COMMON_H_
    #define _COMMON_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    #define FTOK_FILE          "/home/delphi/ftok.file"
    #define FTOK_ID            1
    
    #define SHM_RD_PERMISSION  0444
    #define SHM_WR_PERMISSION  0222
    #define SHM_RW_PERMISSION  (SHM_RD_PERMISSION | SHM_WR_PERMISSION)
    
    #endif
    

    shmcreate.c

    #include "common.h"
    
    int main(int argc, char **argv)
    {
        int length = atoi(argv[1]);
        int oflag = IPC_CREAT | SHM_RW_PERMISSION;
        int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), length, oflag);
    
        if (shmid >= 0)
        {
            printf("shmget create success, shmid = %d
    ", shmid);
        }
    
        return 0;
    }
    

    shmrmid.c

    #include "common.h"
    
    int main(int argc, char **argv)
    {
        int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
        shmctl(shmid, IPC_RMID, NULL);
    
        return 0;
    }
    

    shmwrite.c

    #include "common.h"
    
    int main(int argc, char **argv)
    {
        int shmid;
        unsigned char *shmadd;
        struct shmid_ds buf;
        int i;
    
        shmid   = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
        shmadd  = shmat(shmid, NULL, 0);
        shmctl(shmid, IPC_STAT, &buf);
    
        for (i = 0; i < buf.shm_segsz; i++)
        {
            *shmadd++ = i % 256;
        }
    
        return 0;
    }
    

    shmread.c

    #include "common.h"
    
    int main(int argc, char **argv)
    {
        int shmid;
        unsigned char *shmadd;
        unsigned char v;
        struct shmid_ds buf;
        int error = 0;
        int i;
    
        shmid   = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
        shmadd  = shmat(shmid, NULL, 0);
        shmctl(shmid, IPC_STAT, &buf);
    
        for (i = 0; i < buf.shm_segsz; i++)
        {
            v = *shmadd++;
    
            if (v != (i % 256))
            {
                printf("error: shmadd[%d] = %d
    ", i, v);
                error++;
            }
        }
    
        if (error == 0)
        {
            printf("all of read is ok
    ");
        }
    
        return 0;
    }
    

    代码测试

  • 相关阅读:
    python 测试日志的简单写法
    selenium web端滑动页面查找元素
    selenium之内嵌网页iframe切换
    selenium多窗口切换,及其关闭
    selenium 双击操作右击操作鼠标悬停
    selenium web元素定位合集
    三大浏览器的驱动地址
    app 怎么区分是原生
    django 处理图片上传
    django时区问题
  • 原文地址:https://www.cnblogs.com/songhe364826110/p/11546043.html
Copyright © 2011-2022 走看看