共享内存
共享内存用于进程间传输大数据。
常用函数
key_t ftok( const char * fname, int id )
功能:系统IPC键值的格式转换函数
名字 | 备注 | |
输入参数 | fname | 指定的文件名 |
id | 子序号,虽然是int类型,但是只使用8bit(1-255) | |
返回值 | key_t | 进程间通信键值 |
int shmget(key_t key, size_t size,int shmflg);
功能:创建或打开一块共享内存
名字 | 备注 | |
输入参数 | key | 进程间通信键值,ftok()的返回值 |
size | 共享存储段的长度(字节) | |
shmflg | 标识函数的行为以及共享内存的权限,取值如下 IPC_CREAT:如果不存在旧创建 IPC_EXCL:如果已经存在则返回失败 位或权限位:共享内存或权限为后可以设置共享内存的访问权限,跟open()函数的mode_t一样。 | |
返回值 | int | 成功:返回共享内存标识符 失败:-1 |
void *shmat(innt shmid,const void *shmaddr,int shmflg);
功能:将一个共享内存段映射到调用进程的数据段中。让进程和共享内存建立一种联系,让进程某个指针指向该共享内存。
名字 | 备注 | |
输入参数 | shmid | 共享内存的标识符,shmget()的返回值 |
shmaddr | 共享内存的映射地址,推荐用NULL(由系统自动指定分配) | |
shmflg | 共享内存段的访问权限和映射条件,通常为0,由内核选择地址 0:共享内存具有可读可写权限 SHM_RDONLY:只读 SHM_RND:取整
| |
返回值 | void | 成功:共享内存段映射地址(相当于这个指针就指向共享内存) 失败:-1 |
int shmdt(const void * shmaddr);
功能:解除对共享内存的映射
名字 | 备注 | |
输入参数 | shmaddr | 共享内存映射地址 |
返回值 | int | 成功:0 失败:-1 |
int shmctl(int shmid, int cmd.struct shmod_ds *buf);
功能:对共享内存进行控制
名字 | 备注 | |
输入参数 | shmid | shmget函数返回的共享内存标识符 |
cmd | IPC_RMID:删除共享内存 IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中 IPC_SET:改变共享内存的状态 | |
buf | 结构体shmid_ds | |
返回值 | int | 成功:0 错误:-1 |
int ret =shmctl(id,IPC_RMID,NULL)//删除id号的共享储存空间
下面请看代码
server.c
/*
* @Author: your name
* @Date: 2021-05-11 10:42:02
* @LastEditTime: 2021-05-11 11:06:32
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /code/sharedmemory.c
*/
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <sys/types.h>
#include<sys/shm.h>
int main(void){
int id;
char *p=NULL;
key_t key = ftok("./shd",12);
if(key<0){
perror("ftok error");
exit(1);
}
id = shmget(key,4096,IPC_CREAT|0666);
if(id<0){
perror("shmget error");
exit(1);
}
p = shmat(id,NULL,0);
if(p<0){
perror("shmat error");
exit(1);
}
char buf[4096]={0};
scanf("%s",buf);
printf("scnaf:%s\r\n",buf);
strncpy(p,buf,strlen(buf));
printf("write successfully\r\n");
int ret= shmdt(p);
if(ret<0){
perror("shmdt error");
exit(1);
}
exit(0);
}
client.c
/*
* @Author: your name
* @Date: 2021-05-11 10:59:03
* @LastEditTime: 2021-05-11 11:11:22
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /code/sharememory1.c
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/shm.h>
#include <sys/types.h>
// #include<s>
int main(){
key_t key = ftok("./shd",12);
if(key<0){
perror("ftok error");
exit(1);
}
int id = shmget(key,4096,IPC_CREAT|0666);
if(id<0){
perror("shmget error");
exit(1);
}
char *p = (char *)shmat(id,NULL,0);
if(p<0){
perror("shmat error");
p=NULL;
}
printf("get buf=%s\r\n",p);
if(shmdt(p)<0){
perror("shmdt error");
exit(1);
}
exit(0);
}
执行以上代码
server.c
yates@yates-virtual-machine:~/test/code$ ./sharememory
123456
scnaf:123456
write successfully
看见输入123456成功写入
client.c
yates@yates-virtual-machine:~/test/code$ ./sharememory1
get buf=123456
看到内存返回123456,说明内存读取成功。
在命令函输入 "ipcs -m",看到创建一个4096bytes共享内存成功了,shmid 为54。
yates@yates-virtual-machine:~/test/code$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 11 yates 600 524288 2 dest
0x00000000 14 yates 600 524288 2 dest
0x00000000 15 yates 600 524288 2 dest
0x00000000 27 yates 600 524288 2 dest
0x00000000 32 yates 600 524288 2 dest
0x00000000 47 yates 600 4194304 2 dest
0x0c01c1af 54 yates 666 4096 0
0x00000000 55 yates 600 524288 2 dest
最后可以通过输入 ipcrm -m shmid 删除共享内存,例如在以上看到shmid 为54,所以输入"ipcrm -m 54",成功删除。