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; } 代码测试 (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |