key_t ftok(const char* pathname, int proj_id);
所需头文件:sys/types.h, sys/ipc.h
功能:使用由给定路径名指定的文件标识以及proj_id的最低8位来生成一个key_t类型system V IPC键。
pathname:路径名
proj_id:任意一个字符
返回值:成功返回生成的key_t类型的值,失败返回-1并设置errno。
int shmget(key_t key, size_t size, int shmflg);
所需头文件:sys/ipc.h,sys/shm.h
功能:生成共享内存段标识符
key:由ftok生成的system IPC键
size:共享内存区大小
shmflg:同open函数的权限位,也可以用8进制表示
返回值:成功返回共享内存段标识符,失败返回-1并设置errno。
| 名称 | 说明 |
|---|---|
| IPC_CREAT | 创建一个新的段 |
| IPC_EXCL | 如果存在则失败 |
void* shmat(int shmid, const void* shmaddr, int shmflg);
所需头文件:sys/typs.h,sys/shm.h
功能:获取共享内存区
shmid:要映射的共享内存标识区
shmaddr:将共享内存区映射到指定地址(如果为NULL,则表示由系统自动完成映射)
shmflg:
SHM_RDONLY:共享内存只读
0:共享内存可读写
返回值:成功返回映射后的地址,失败返回-1并设置errno。
int shmdt(const void* shmaddr);
所需头文件 :sys/types.h,sys/shm.h
功能:回收分配的共享内存
shmaddr:共享内存映射后的地址
int shmctl(int shmid, int cmd, struct shmid_ds* buf);
所需头文件:sys/ipc.h,sys/shm.h
shmid:共享内存标识符
cmd:执行的操作
buf:共享内存属性
| 名称 | 说明 |
|---|---|
| IPC_RMID | 清除共享内存标识符 |
| IPC_STAT | 获取共享标识符的信息 |
| IPC_SET | 更改shmid的属性,并更新最后修改时间 |
代码:
read.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>
#include <string.h>
int main(void) {
key_t key;
int shmid;
char* shm;
key = ftok("./app", 'c');
if (key == -1) {
perror("ftok err");
return -1;
}
shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666 );
if (shmid == -1) {
if (errno == EEXIST)
shmid = shmget(key, 128, 0666);
else {
perror("shmget err");
return -1;
}
}
printf("shmid:%d\n", shmid);
printf("%#x\n", key);
shm = (char*)shmat(shmid, NULL, 0);
if (shm == (char*)-1) {
perror("shmat err");
return -1;
}
while(1) {
fgets(shm, 32, stdin);
//printf("shm:%s", shm);
if(strncmp(shm, "quit", 4) == 0) {
break;
}
}
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>
#include <string.h>
int main(void) {
key_t key;
int shmid;
char* shm;
key = ftok("./app", 'c');
if (key == -1) {
perror("ftok err");
return -1;
}
shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666 );
if (shmid == -1) {
if (errno == EEXIST)
shmid = shmget(key, 128, 0666);
else {
perror("shmget err");
return -1;
}
}
printf("shmid:%d\n", shmid);
printf("%#x\n", key);
shm = (char*)shmat(shmid, NULL, 0);
if (shm == (char*) -1) {
perror("shmat err");
return -1;
}
while(1) {
if(strncmp(shm, "quit", 4) == 0) {
break;
}
printf("shm:%s", shm);
}
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
执行结果:

