共享内存使用的函数介绍
1. shmget函数
该函数用来创建共享内存:
int shmget(key_t key, size_t size, int shmflg);
参数:
key : 和信号量一样,程序需要提供一个参数key,
它有效地为共享内存段命名。
有一个特殊的键值IPC_PRIVATE,
它用于创建一个只属于创建进程的共享内存,
通常不会用到。
size: 以字节为单位指定需要共享的内存容量。
shmflag: 包含9个比特的权限标志,
它们的作用与创建文件时使用的mode标志是一样。
由IPC_CREAT定义的一个特殊比特必须和权限标志按位或
才能创建一个新的共享内存段。
NOTE:
权限标志对共享内存非常有用,
因为它允许一个进程创建的共享内存可以被共享内存的创建者所拥有的进程写入,
同时其它用户创建的进程只能读取共享内存。
我们可以利用这个功能来提供一种有效的对数据进行只读访问的方法,
通过将数据放共享内存并设置它的权限,
就可以避免数据被其他用户修改。
返回值:
创建成功,则返回一个非负整数,即共享内存标识;
如果失败,则返回-1.
2. shmat函数
第一次创建共享内存段时,它不能被任何进程访问。
要想启动对该内存的访问,
必须将其连接到一个进程的地址空间。
这个工作由shmat函数完成:
void *shmat(int shm_id, const void *shm_addr, int shmflg);
参数:
shm_id : 由shmget返回的共享内存标识。
shm_add: 指定共享内存连接到当前进程中的地址位置。
它通常是一个空指针,
表示让系统来选择共享内存出现的地址。
shmflg : 是一组标志。
它的两个可能取值是:
SHM_RND, 和shm_add联合使用,
用来控制共享内存连接的地址。
SHM_RDONLY, 它使连接的内存只读
返回值:
如果调用成功, 返回一个指向共享内存第一个字节的指针;
如果失败,返回-1.
共享内存的读写权限由它的属主(共享内存的创建者),
它的访问权限和当前进程的属主决定。
共享内存的访问权限类似于文件的访问权限。
3. shmdt
将共享内存从当前进程中分离。
int shmdt(const void *shm_addr);
shm_addr: shmat返回的地址指针。
成功时,返回0,
失败时,返回-1.
NOTE:
共享内存分离并未删除它,
只是使得该共享内存对当前进程不再可用。
4. shmctl
共享内存的控制函数
int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
shmid_ds结构至少包含以下成员:
struct shmid_ds {
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
}
参数:
shm_id : 是shmget返回的共享内存标识符。
command: 是要采取的动作,
它可以取3个值:
IPC_STAT 把shmid_ds结构中的数据设置为共享内存的当前关联值
IPC_SET 如果进程有足够的权限,
就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID 删除共享内存段
buf : 是一个指针,
包含共享内存模式和访问权限的结构。
返回值:
成功时,返回0,
失败时,返回-1.
代码实现
shmwrite.c
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.h> typedef struct stu { char name[32]; int age; } STU; int main(int argc, char *argv[]) { int shmid; shmid = shmget((key_t)1234,sizeof(STU),IPC_CREAT | 0666); if (shmid == -1) { printf("shmget failed "); exit(1); } STU *p; p = shmat(shmid,NULL,0); if (p == (void*)-1) { printf("shmat failed "); exit(1); } strcpy(p->name, "zhangsan"); p->age = 20; while(1) { if(memcmp(p, "quit",4) == 0) { break; } } shmdt(p); shmctl(shmid,IPC_RMID,NULL); return 0; }
shmread.c
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> typedef struct stu { char name[32]; int age; } STU; int main(int argc, char *argv[]) { int shmid; shmid = shmget((key_t)1234,0,0); if (shmid == -1) { printf("shmget failed "); exit(1); } STU *p; p = shmat(shmid,NULL,0); if (p == (void*)-1) { printf("shmat failed "); exit(1); } printf("name = %s, age = %d ",p->name,p->age); memcpy(p,"quit",4); shmdt(p); return 0; }
Makefile
.PHONY: clean all CC=gcc CFLAGS=-Wall -g BIN=shmwrite shmread all:$(BIN) %.o:%.c $(cc) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(bin)
参考:http://blog.chinaunix.net/uid-26000296-id-3421346.html