POSIX 共享内存

POSIX 共享内存的介绍与使用。


mq_open函数

  • 功能:用来创建或打开一个共享内存
  • 原型:

    1
    int shm_open(const char *name, int oflag, mode_t mode);
  • 参数:

    • name:共享内存对象的名字
    • oflag:与open函数类似,可以是O_RDONLY、O_RDWR,还可以按位或上O_CREAT、O_EXCEL、O_TRUNC等
    • mode:此参数总是需要设置,如果oflag没有指定O_CREAT,可以指定为0
  • 返回值:成功返回非负整数文件描述符;失败返回-1

ftruncate函数

  • 功能:修改共享内存大小
  • 原型:

    1
    int ftruncate(int fd, off_t length);
  • 参数:

    • fd:文件描述符
    • length:长度
  • 返回值:成功返回0;失败返回-1

fstat函数

  • 功能:获取共享内存对象信息
  • 原型:

    1
    int fstat(int fd, struct stat *buf);
  • 参数:

    • fd:文件描述符
    • buf:返回共享内存状态
  • 返回值:成功返回0;失败返回-1

shm_unlink函数

  • 功能:删除一个共享内存
  • 原型:

    1
    int shm_unlink(const char *name);
  • 参数:

    • name:共享内存对象的名字
  • 返回值:成功返回0;失败返回-1

mmap函数

  • 功能:将文件或者设备空间映射到共享内存区
  • 原型:

    1
    void *mmap(void *addr, size_t len, int port, int flags, int fd, off_t offset);
  • 参数:

    • addr:要映射的起始地址,通常指定为NULL,让内核自主选择
    • len:要映射到进程地址空间的字节数
    • port:映射区保护方式
    • flags:标志
    • fd:文件描述符
    • offset:从文件头开始的偏移量
  • 返回值:成功返回映射到的内存区的起始地址;失败返回-1

保护方式:

port 说明
PROT_READ 页面可读
PROT_WRITE 页面可写
PROT_EXEC 页面可执行
PROT_NONE 页面不可访问

flags:

flags 说明
MAP_SHARED 变动是共享的
MAP_PRIVATE 变动是私有的
MAP_FIXED 准确解释addr参数
MAP_ANONYMOUS 建立匿名映射区,不涉及文件

POSIX 共享内存使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*shmwrite.c*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct stu {
char name[32];
int age;
} STU;
int main() {
int shmid;
shmid = shm_open("/abc", O_RDWR, 0);
if (shmid == -1) {
ERR_EXIT("mq_open");
}
printf("shm_open succ\n");
struct stat buf;
if (fstat(shmid, &buf) == -1) {
ERR_EXIT("fstat");
}
STU *p;
p = mmap(NULL, buf.st_size, PROT_WRITE, MAP_SHARED, shmid, 0);
if (p == MAP_FAILED) {
ERR_EXIT("mmap");
}
strcpy(p->name, "test");
p->age = 20;
close(shmid);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*shmread.c*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct stu {
char name[32];
int age;
} STU;
int main() {
int shmid;
shmid = shm_open("/abc", O_RDWR, 0);
if (shmid == -1) {
ERR_EXIT("mq_open");
}
printf("shm_open succ\n");
struct stat buf;
if (fstat(shmid, &buf) == -1) {
ERR_EXIT("fstat");
}
STU *p;
p = 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;
}