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; };
shmget用于创建一个新的共享内存或打开一个已存在的共享内存。
//成功返回共享内存标识符, int shmget(key_t key, size_t size, int oflag);
shmat用于把shmget创建或打开的共享内存连接到调用进程的地址空间。
//成功返回映射区起始地址,失败返回-1 void *shmat(int shmid, const void *shmaddr, int flag);
shmdt删除由shmat建立的连接。
//成功返回0,失败返回-1 int shmdt(const void *shmaddr);
shmctl用于对共享内存的各种控制操作。
//成功返回0,失败返回-1 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
cmd可使用的命令有三个:
#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
#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\n", shmid); } return 0; }
#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; }
#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; }
#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\n", i, v); error++; } } if (error == 0) { printf("all of read is ok\n"); } return 0; }
如对本文有疑问, 点击进行留言回复!!
linux下文本编辑器vim的使用方法(复制、粘贴、替换、行号、撤销、多文件操作)
网友评论