ftok
通过文件路径 pathname 以及 proj_id 获得键值key(键值:共享内存的标识),只要文件路径和proj_id不变,key值就不变
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
原型:
key_t ftok(const char *pathname, int proj_id);
参数:
char *pathname:文件路径(目录文件或是普通文件);
int proj_id:非0参数,用户自定义;
返回值:
成功,返回key值;
失败,返回-1,更新errno;
例程:
key_t key = ftok("./", 'a');
if(key < 0)
{
perror("ftok");
return -1;
}
printf("key = %x\n", key);
shmget
创建或打开共享内存对象
头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
原型:
int shmget(key_t key, size_t size, int shmflg);
参数:
key_t key:键值,提前约定或ftok函数创建获得;
size_t size:指定创建的共享内存空间大小,以字节为单位;
int shmflg:设置共享内存的访问权限,参数如下:
IPC_CREAT:若共享内存对象不存在则创建,否则打开已经存在的共享内存对象;
IPC_EXCL:若共享内存对象不存在则创建,否则返回出错;
IPC_NOWAIT:(非阻塞)如果本操作需要等待,则直接返回错误;
IPC_CREAT|0666:如果内核中不存在与key值相同的共享内存,则创建共享内存,并设置8进制权限(按位或)。如果存在,则直接返回共享内存标识符shmid;
返回值:
成功,返回共享内存标识符:shmid;
失败,返回-1,更新errno;
例程:
int shmid = shmget(key, N, IPC_CREAT|0664);
if(shmid < 0)
{
perror("shmget");
return -1;
}
printf("shmid = %d\n", shmid);
shmat
将共享内存空间连接到进程的虚拟地址空间
头文件:
#include <sys/types.h>
#include <sys/shm.h>
原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
int shmid:共享内存对象标识id;
void *shmaddr:共享内存映射到进程空间的虚拟地址,填NULL,让系统决定共享内存连接到进程空间中的哪个地址;
int shmflg:参数如下:
0:可读可写;
SHM_RDONLY:共享内存被限制为只读;
返回值:
成功,返回共享内存映射到用户空间的地址;
失败,返回(void *) -1,更新errno;
例程:
void* shmaddr = NULL;
shmaddr = shmat(shmid, NULL, 0);
if(shmaddr == (void*)-1)
{
perror("shmat");
return -1;
}
printf("shmaddr = %p\n", shmaddr);
shmdt
断开进程空间与共享内存空间的连接
头文件:
#include <sys/types.h>
#include <sys/shm.h>
原型:
int shmdt(const void *shmaddr);
参数:
void *shmaddr:指定要断开映射的内存空间在进程空间中的连接地址;
返回值:
成功,返回0;
失败,返回-1,更新errno;
例程:
if(shmdt(shmaddr) < 0)
{
perror("shmdt");
return -1;
}
shmctl
共享内存控制操作,常用于删除
头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
原型:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
int shmid:共享内存的shmid
int cmd:控制方式,参数如下:
IPC_RMID:删除共享内存,第三个参数,填NULL;
IPC_STAT:获取共享内存对象的内核结构值,存放到第三个参数中;
IPC_SET:设置共享内存对象的内核结构值;
struct shmid_ds *buf:指向shmid_ds结构的指针;
返回值:
成功,返回0;
失败,返回-1,更新errno;
例程:
if(shmctl(shmid, IPC_RMID, NULL) < 0)
{
perror("shmctl");
return -1;
}
往共享内存中 写数据
strcpy((char*)shmaddr,"hello world");
向共享内存中 读数据
char str[20] = "";
strcpy(str,(char*)shmaddr);
应用例程
使用共享内存实现,一个进程写入数据,一个进程读取数据
进程1:写入数据到共享内存
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>
#define N 20
int main(int argc, const char *argv[])
{
//创建共享内存key值
key_t key = ftok("./",'a');
if(key < 0){
perror("ftok");
return -1;
}
printf("key = %x\n",key);
//创建共享内存
int shmid = shmget(key,N,IPC_CREAT|0664);
if(shmid < 0){
perror("shmget");
return -1;
}
printf("shmid = %d\n",shmid);
//映射到虚拟内存地址
void* shmaddr = shmat(shmid,NULL,0);
if(shmaddr == (void*)-1){
perror("shmat");
return -1;
}
//将数据存入共享内存
strcpy((char*)shmaddr,"Shared Memory");
//断开映射
if(shmdt(shmaddr) < 0){
perror("shmdt");
return -1;
}
return 0;
}
进程2:从共享内存中读取数据
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>
#define N 20
int main(int argc, const char *argv[])
{
//获取共享内存key值
key_t key = ftok("./",'a');
if(key < 0){
perror("ftok");
return -1;
}
printf("key = %x\n",key);
//创建共享内存
int shmid = shmget(key,N,IPC_CREAT|0664);
if(shmid < 0){
perror("shmget");
return -1;
}
printf("shmid = %d\n",shmid);
//映射到虚拟内存地址
void* shmaddr = shmat(shmid,NULL,0);
if(shmaddr == (void*)-1){
perror("shmat");
return -1;
}
//从虚拟内存中获取数据拷贝
char str[N] = "";
strcpy(str,(char*)shmaddr);
puts(str);
//断开映射
if(shmdt(shmaddr) < 0){
perror("shmdt");
return -1;
}
//删除共享内存
if(shmctl(shmid,IPC_RMID,NULL) < 0){
perror("shmctl");
return -1;
}
return 0;
}
结果
本文链接:https://shengto.top/c/shm_routine.html
转载时须注明出处及本声明