SystemV:
用到的函数:
ftok : 生成一个32位整数, shmget第一个参数需要用到. 相同的key,返回相同的shmid
shmget : 用于创建或获取一个共享内存。返回一个id用于标识这块IPC对象;
shmat: 把共享内存映射到进程地址空间.
shmdt : 断开映射.与shmat,作用相反;
shmctl : 获取共享内存属性(大小,权限,创建时间,pid....). 删除共享内存
Posix: 基于文件
共享内存信号量结合使用 mmap : 共享内存信号量
shm_open: 创建或打开一个 /dev/shm 的共享内存
shm_unlink : 删除 /dev/shm 共享内存
mmap : 把共享内存(文件) 映射到进程内 . 用于读写, 相对于 shmat 的用作
ftruncate : 更改内存大小
例子:
System V:
shmget.c :
创建一个共享内存
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
if(argc != 3){
printf("pathname , size\n");
return 0;
}
char *pathname = argv[1];
int len = atoi(argv[2]);
printf("pathname:%s, len:%d\n",pathname,len);
//ftok -> 生成一个key , 用于标示一个ipc对象.
int key = ftok(pathname , 0);
printf("key : %d\n" , key);
//创建或者获取一个共享内存. 返回一个共享内存的标示.
//相同的key , 返回相同的shmid
int shmid = shmget(key,len,IPC_CREAT|0644);
printf("shmid:%d\n",shmid);
//映射到当前的进程地址空间中.之后进行读写
char*p = (char*)shmat(shmid,NULL,0);
printf("p:%p\n",p);
struct shmid_ds shmbuf;
//shmctl 可获取shm的状态,也可以删除共享内存
shmctl(shmid,IPC_STAT,&shmbuf);
printf("size:%ld,creator pid:%d,links:%ld\n",
shmbuf.shm_segsz,shmbuf.shm_cpid,shmbuf.shm_nattch);
//取消映射,相当于断开链接.注意,删除需要用shmctl
shmdt(p);
return 0;
}
shmrmid.c :
用于删除一个共享内存
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
if(argc != 2){
printf("pathname \n");
return 0;
}
int key = ftok(argv[1],0);
printf("key:%d\n" , key);
int shmid = shmget(key,0,0644);
printf("shmid:%d\n" , shmid);
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
shmwrite.c : 写入共享内存
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if(argc != 2){
puts("pathname");
return 0;
}
int key = ftok(argv[1],0);
int shmid = shmget(key,0,0664);
printf("key:%d, shmid:%d\n",key,shmid);
char *ptr= (char*)shmat(shmid,NULL,0);
char *p = ptr;
printf("ptr:%p\n", ptr);
struct shmid_ds shmbuf;
shmctl(shmid,IPC_STAT,&shmbuf);
printf("shm size:%ld\n",shmbuf.shm_segsz);
for(int i =0 ; i < shmbuf.shm_segsz;++i)
*p++ = i;
shmdt(ptr);
return 0;
}
shmread.c : 读取共享内存
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if(argc != 2){
puts("pathname");
return 0;
}
int key = ftok(argv[1],0);
int shmid = shmget(key,0,0664);
char *ptr = (char*)shmat(shmid,NULL,0);
char *p = ptr;
struct shmid_ds shmbuf;
shmctl(shmid,IPC_STAT,&shmbuf);
printf("shm size :%ld\n",shmbuf.shm_segsz);
for(int i = 0 ; i < shmbuf.shm_segsz;++i)
printf("%c ",*p++);
puts("");
shmdt(ptr);
return 0;
}
Posix :
shm_open.c
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc , char ** argv , char ** env)
{
if(argc !=3){
printf("shm_open path size ?\n");
return 0;
}
int flags = O_RDWR|O_CREAT;
int size = atoi(argv[2]);
int shmfd = shm_open(argv[1],flags,0664);
printf("shmfd :%d\n",shmfd);
ftruncate(shmfd,size);
struct stat stat;
fstat(shmfd,&stat);
printf("shm size:%ld\n" , stat.st_size);
char * ptr = (char*)mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,
shmfd,0);
printf("mmap :%p\n" , ptr);
return 0;
}
shm_unlink.c
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc , char ** argv , char ** env)
{
if(argc !=2){
puts("shm_unlink path");
return 0;
}
shm_unlink(argv[1]);
return 0;
}
shm_write.c
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc , char ** argv , char ** env)
{
if(argc != 2){
puts("shm_write path");
return 0;
}
int shmfd = shm_open(argv[1],O_RDWR,0664);
printf("shmid : %d\n" , shmfd);
struct stat stat;
fstat(shmfd,&stat);
printf("shm size : %ld\n" , stat.st_size);
char * ptr = mmap(NULL,stat.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,
shmfd,0);
close(shmfd);
char * p = ptr;
for(int i = 0; i < stat.st_size; ++i)
*p++ = i;
return 0;
}
shm_read.c
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc , char ** argv , char ** env)
{
if(argc != 2){
puts("shm_read path");
return 0;
}
int shmfd = shm_open(argv[1],O_RDWR,0664);
struct stat stat;
fstat(shmfd,&stat);
char * ptr = (char*)mmap(NULL,stat.st_size,PROT_READ,MAP_SHARED,shmfd,0);
char * p = ptr;
for(int i =0 ; i < stat.st_size;++i)
printf("%c " ,*p++);
puts("");
close(shmfd);
return 0;
}