Posted on 2008-02-19 11:30
ZelluX 阅读(446)
评论(0) 编辑 收藏 所属分类:
Linux 、
System
《边干边学》上一个简单的共享内存的例程:
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define KEY 1234
#define SIZE 1024
int main()
{
int shmid;
char *shmaddr;
struct shmid_ds buf;
shmid = shmget(KEY, SIZE, IPC_CREAT | 0600);
if (shmid == -1) {
printf("Failed in creating shared memory: %s\n", strerror(errno));
return 0;
}
if (fork() == 0) {
shmaddr = (char *) shmat(shmid, NULL, 0);
if (shmaddr == (void *) -1) {
printf("Failed in connecting to the shared memory: %s\n", strerror(errno));
return 0;
}
strcpy(shmaddr, "Hello, this is child process!\n");
shmdt(shmaddr);
return 0;
} else {
sleep(3);
shmctl(shmid, IPC_STAT, &buf);
printf("Size of the shared memory: ");
printf("shm_segsz = %d bytes\n", buf.shm_segsz);
printf("Process id of the creator: ");
printf("shm_cpid = %d\n", buf.shm_cpid);
printf("Process id of the last operator: ");
printf("shm_lpid = %d\n", buf.shm_lpid);
shmaddr = (char *) shmat(shmid, NULL, 0);
if (shmaddr == (void *) -1) {
printf("Failed in connecting the shared memory: %s\n", strerror(errno));
return 0;
}
printf("The content of the shared memory: %s\n", shmaddr);
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
}
}
主要的API:
shmget 创建一块共享内存
shmat 将一块已经存在的共享内存映射到一个进程的地址空间
shmdt 取消一个进程的地址空间中的一块共享块的映射
shmctl 管理共享内存,和ioctl的风格很像
每一个新创建的共享都由一个shmid_ds{}表示。struct shmid_ds在linux/shm.h中的定义:
/**//* Obsolete, used only for backwards compatibility and libc5 compiles */
struct shmid_ds {
struct ipc_perm shm_perm; /**//* operation perms */
int shm_segsz; /**//* size of segment (bytes) */
__kernel_time_t shm_atime; /**//* last attach time */
__kernel_time_t shm_dtime; /**//* last detach time */
__kernel_time_t shm_ctime; /**//* last change time */
__kernel_ipc_pid_t shm_cpid; /**//* pid of creator */
__kernel_ipc_pid_t shm_lpid; /**//* pid of last operator */
unsigned short shm_nattch; /**//* no. of current attaches */
unsigned short shm_unused; /**//* compatibility */
void *shm_unused2; /**//* ditto - used by DIPC */
void *shm_unused3; /**//* unused */
};其中存放权限信息的ipc_perm{}的定义为:
include/linux/ipc.h
/**//* Obsolete, used only for backwards compatibility and libc5 compiles */
struct ipc_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned short seq;
};mode为该共享的内存的读写权限,和chmod的参数有点像。mode低九位定义了访问许可,解释如下:
0400 用户可读 0200用户可写 0040 组成员可读 0020 组成员可写 0004 其他用户可读 0002 其他用户可写
没有执行位 0100 0010 和 0001