一、共享内存
1、获取一个键值 ftok(3)
2、使用键值获取共享内存的ID shmget(2)
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:分配一块共享内存段,获取和key值相关的共享内存段的ID
参数:
key:ftok(3)的返回值
size:指定共享内存段的尺寸
shmflg:
IPC_CREAT:如果没有和key值相关的内存段就创建
IPC_EXCL:如果有相关的内存段报错(和IPC_CREAT一起存在时)
mode:指定共享内存段的权限
返回值:-1 错误 errno被设置
成功 返回共享内存段的ID
编写代码创建一个共享内存段,获取该内存段的id(shmget.c)
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int main(void) {
key_t key; //用于存储键值
//获取键值
key = ftok(".", 31);
if(key == -1) {
perror("ftok");
return -1;
}
printf("key=0x%x\n",key);
//获取shmid
int shmid = shmget(key, 1024, IPC_CREAT|0664);
if(shmid == -1) {
perror("shmget");
return -1;
}
printf("shmid=0x%x\n", shmid);
return 0;
}
tarena@ubuntu:~/day/day34$ a.out
key=0x1f08241a
shmid=0x10001
tarena@ubuntu:~$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 tarena 600 393216 2 dest
0x1f08241a 65537 tarena 664 1024 0
3、将共享内存关联到进程的虚拟地址空间shmat(2)
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将一块共享内存段添加到内存的地址空间
参数:
shmid:指定了共享内存段的ID
shmaddr:NULL 由系统选择地址
shmflg:
SHM_RDONLY:共享内存段只读
0:可都可写
返回值:成功 返回附加到进程内存段的地址
错误 (void *) -1 errno被设置
4、向内存读写数据
5、解除进程的虚拟地址到共享内存的关联shmdt(2)
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
功能:解除共享内存段和进程地址空间的关联
参数:
shmaddr:指定了共享内存段的起始地址
返回值:成功 0
错误 -1 errno被设置
举例:使用共享内存段实现进程间的通信(shmA.c shmB.c)
shmA.c:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int main(void) {
key_t key;
key = ftok(".", 31);
if(key == -1) {
perror("ftok");
return -1;
}
printf("key=0x%x\n",key);
int shmid = shmget(key, 1024, IPC_CREAT|0664);
if(shmid == -1) {
perror("shmget");
return -1;
}
//将共享内存段附加到进程的地址空间
void *p = shmat(shmid, NULL, 0);
if(p == (void*)-1) {
perror("shmat");
return -1;
}
*((int*)p) = 321;//p的访问方式由void*转换为int*
//解除关联
shmdt(p);
printf("shmid=0x%x\n", shmid);
return 0;
}
命令: tarena@ubuntu:~/day/day34$ A
结果: key=0x1f08241a
shmid=0x10001
shmB.c:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int main(void) {
key_t key;
key = ftok(".", 31);
if(key == -1) {
perror("ftok");
return -1;
}
printf("key=0x%x\n",key);
int shmid = shmget(key, 1024, IPC_CREAT|0664);
if(shmid == -1) {
perror("shmget");
return -1;
}
//将共享内存段附加到进程的地址空间
void *p = shmat(shmid, NULL, 0);
if(p == (void*)-1) {
perror("shmat");
return -1;
}
printf("%d\n",*((int*)p));
//解除关联
shmdt(p);
printf("shmid=0x%x\n", shmid);
return 0;
}
命令: tarena@ubuntu:~/day/day34$ B
结果: key=0x1f08241a
321
shmid=0x10001
分析:共享内存中,在取出数据后,内存中还有数据,只能覆盖不能移除,和消息队列不太一样
【C语言】【unix c】共享内存
最新推荐文章于 2024-09-11 10:16:00 发布