POSIX共享内存
POSIX共享内存不须要自己手动挂载,仅仅要打开成功,就会自己主动挂载.一般挂载在 /dev/shm 文件夹下
cd /dev/shm
od -c xyz1. shm_open 函数
功能:用来创建或打开一个共享内存对象
原型:
int shm_open(const char* name,int oflag,mode_t mode);
參数:
name:共享内存对象的名字
oflag:与open 函数类似,能够是O_RDONLY,O_RDWR,还能够按位或上O_CREAT,O_EXCL,O_TRUNC等.
mode:此參数总是须要设置,假设oflag没有指定 O_CREAT, 能够指定为0;
返回值: 成功返回非负整数文件描写叙述符;失败返回-1
2. ftruncate
功能:改动共享内存对象大小
原型: int ftruncate(int fd,off_t length);
參数:
fd:文件描写叙述符
length:长度
返回值: 成功返回0,失败返回-1
3.fstat
功能:获取共享内存对象信息
原型:
int fstat(int fd,struct stat *buf);
參数:
fd: 文件描写叙述符
buf: 返回共享内存状态
返回值: 成功返回0,失败返回-1
4. shm_unlink函数
功能:删除一个共享内存对象
原型: int shm_unlink(const char* name);
參数:
name:共享内存对象的名字
返回值:
成功返回0,失败返回-1;
5.mmap
功能:将共享内存对象映射到进程地址空间.
原型:
void *mmap(void *addr,size_t len,int prot,int flags,int fd,off_t offset);
參数:
addr:要映射的起始地址,通常指定为NULL,让内核自己主动选择
len: 映射到进程地址空间的字节数
prot: 映射区保护方式
flags: 标志
fd: 文件描写叙述符
offset: 从文件头開始的偏移量
返回值: 成功返回映射到的内存区的起始地址,失败返回-1
注意:
ERRORS
EACCES A file descriptor refers to a non-regular file. Or MAP_PRIVATE
was requested, but fd is not open for reading. Or MAP_SHARED
was requested and PROT_WRITE is set, but fd is not open in
read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is
append-only.
shm_open.c
#include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define ERR_EXIT(M) \ do \ { \ perror(M); \ exit(EXIT_FAILURE); \ }while(0); typedef struct stu { char name[32]; int age; }STU; int main(void) { int shmid; //用来创建或打开一个共享内存对象 shmid = shm_open("/xyz",O_CREAT | O_RDWR,0666); if(shmid == -1) ERR_EXIT("shm_open err"); printf("shm_open success\n"); if( ftruncate(shmid,sizeof(STU)) == -1 ) //改动共享内存对象大小 ERR_EXIT("ftruncate"); struct stat buf; if(fstat(shmid,&buf) == -1) /// get file status ERR_EXIT("fstat err"); printf("size=%ld mode=%o\n",buf.st_size,buf.st_mode & 0777); close(shmid); // 只须要一个close就能够关闭 return 0; }
shm_unlink.c
#include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define ERR_EXIT(M) \ do \ { \ perror(M); \ exit(EXIT_FAILURE); \ }while(0); int main(void) { shm_unlink("/xyz"); return 0; }
shm_write.c
#include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define ERR_EXIT(M) \ do \ { \ perror(M); \ exit(EXIT_FAILURE); \ }while(0); typedef struct stu { char name[32]; int age; }STU; int main(void) { int shmid; shmid = shm_open("/xyz",O_RDWR,0); // 这里必须是O_RDWR才干映射成功 if(shmid == -1) ERR_EXIT("shm_open err"); printf("shm_open succ\n"); struct stat buf; if(fstat(shmid,&buf) == -1) ERR_EXIT("fstat err"); STU *p; //将共享内存对象映射到进程地址空间. p = mmap(NULL,buf.st_size,PROT_WRITE,MAP_SHARED,shmid,0); if(p == MAP_FAILED) ERR_EXIT("mmap err"); strcpy(p->name,"cjl"); // 依据映射的地址,写入数据 p->age = 20; close(shmid); // 只须要一个close就能够关闭 return 0; }
shm_read.c
#include<stdio.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/types.h> #include<unistd.h> #include<errno.h> #include<fcntl.h> #include<sys/stat.h> #include<sys/mman.h> #include<string.h> #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) typedef struct stu { char name[32]; int age; } STU; int main(void) { int shmid; shmid = shm_open("/xyz", O_RDONLY, 0); if (shmid == -1) ERR_EXIT("shm_open"); struct stat buf; if (fstat(shmid, &buf) == -1) ERR_EXIT("fstat"); printf("size=%ld, mode=%o\n", buf.st_size, buf.st_mode & 0777); STU *p; p = (STU *)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, shmid, 0); if (p == MAP_FAILED) ERR_EXIT("mmap"); printf("name=%s age=%d\n", p->name, p->age); close(shmid); return 0; }
Makefile
.PHONY:clean all CC=gcc CFLAGS=-Wall -g BIN=shm_open shm_unlink shm_write shm_read all:$(BIN) %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ shm_open:shm_open.o $(CC) $(CFLAGS) $^ -o $@ -lrt shm_unlink:shm_unlink.o $(CC) $(CFLAGS) $^ -o $@ -lrt shm_write:shm_write.o $(CC) $(CFLAGS) $^ -o $@ -lrt shm_read:shm_read.o $(CC) $(CFLAGS) $^ -o $@ -lrt clean: rm -f *.o $(BIN)