加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

System V共享内存实例介绍

发布时间:2021-11-09 10:26:31 所属栏目:PHP教程 来源:互联网
导读:1. 概述 System V共享内存在概念上类似于Posix共享内存,代之以调用shm_Open后调用mmap的是,先调用shmget,再调用shmat。 对于每个System V共享内存,内核都维护如下的信息结构,它定义在sys/shm.h头文件中,其中带注释的是我们需要关注的成员。 struct shm

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 = %dn", 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] = %dn", i, v);
            error++;
        }
    }
 
    if (error == 0)
    {
        printf("all of read is okn");
    }
 
    return 0;
}
代码测试
 
 
 
 
 
 
 

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读