有两种方法创建共享内存,第一种用shmop提供的函数,第二种通过mmap(2)函数
man shmop 查看共享内存操作函数
shmget( )
获得一个共享存储标识符
函数声明
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
参数含义
第一个参数为ftok(3)函数返回值,如果 key值为 IPC_PRIVATE 则只能用于有亲缘关系
第二个参数为共享内存空间的大小
第三个参数可选(多选用或运算)
IPC_CREAT 创建,需要或上文件权限
IPC_EXCL 与IPC_CREAT一起使用,确保如果消息队列已经创建,则返回失败
返回值
成功返回 共享内存示例
失败返回 -1 并且设置errno 如果标识符使用了IPC_CREAT 和 IPC_EXCL 并且errno的值为EEXIST,代表消息队列已经存在
shmat()
挂载共享内存,将共享内存连接到进程的可用地址上
函数声明
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数含义
第一个参数为共享内存示例
第二个参数如果是NULL,则内核自动分配到进程所在的第一个可用地址上,不传NULL,则分配地址由用户指定;
返回值
成功返回共享内存地址,失败返回-1,设置errno值
shmdt()
卸载共享内存,将共享内存从进程的可用地址上删除
函数声明
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
参数含义
shmaddr为shmdt函数的返回值
shmctl()
移除共享内存
函数声明
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
共享内存示例1
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(void)
{
pid_t pid;
int shmid;
int flag = 1;
shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | IPC_EXCL | 0600);
if (shmid < 0) {
if (errno == EEXIST) {
shmid = shmget(IPC_PRIVATE, 1024, 0);
flag = 0;
} else {
perror("shmid()");
exit(1);
}
}
pid = fork();
if (pid < 0) {
perror("fork()");
goto FORK_ERROR;
}
if (pid == 0) {
void *p = shmat(shmid, NULL, 0);
memcpy(p, "hello world", 11);
shmdt(p);
exit(1);
}
wait(NULL);
void *ptr = shmat(shmid, NULL, 0);
puts((char *)ptr);
shmdt(ptr);
if (flag)
shmctl(shmid, IPC_RMID, NULL);
exit(0);
FORK_ERROR:
if (flag)
shmctl(shmid, IPC_RMID, NULL);
exit(1);
}
网友评论