📜  POSIX共享内存API(1)

📅  最后修改于: 2023-12-03 15:33:44.118000             🧑  作者: Mango

POSIX共享内存API

介绍

POSIX共享内存API是一组用于在多个进程之间共享内存的API。共享内存是一种进程间通信方式,它允许多个进程访问同一块物理内存。相对于其他IPC方式,共享内存的速度更快,因为数据直接存储在物理内存中,而不需要进行复制。

API
shm_open

shm_open函数用于创建或打开一个共享内存对象。它的原型如下:

int shm_open(const char *name, int oflag, mode_t mode);

其中name参数指定了共享内存对象的名称,oflag参数用于指定创建或打开的方式,mode参数用于指定对象的访问权限。

ftruncate

ftruncate函数用于设置共享内存对象的大小。它的原型如下:

int ftruncate(int fd, off_t length);

其中fd参数是shm_open函数返回的共享内存对象的文件描述符,length参数指定对象的大小。

mmap

mmap函数用于将共享内存对象映射到进程的虚拟地址空间中。它的原型如下:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

其中addr参数用于指定映射的地址,通常设置为NULL,系统会自动分配一个合适的地址;length参数指定映射的大小;prot参数指定映射区域的保护方式,常用的值有PROT_READ、PROT_WRITE和PROT_EXEC;flags参数用于设置映射的方式,常用的值有MAP_SHARED和MAP_PRIVATE;fd参数是shm_open函数返回的共享内存对象的文件描述符;offset参数指定从共享内存对象的哪个位置开始映射。

munmap

munmap函数用于解除由mmap函数创建的映射关系。它的原型如下:

int munmap(void *addr, size_t length);

其中addr参数是mmap函数返回的映射起始地址,length参数是映射的大小。

shm_unlink

shm_unlink函数用于删除共享内存对象。它的原型如下:

int shm_unlink(const char *name);

其中name参数指定要删除的共享内存对象的名称。

示例代码

下面是一个简单的示例,演示如何使用POSIX共享内存API创建和访问共享内存:

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define SHARED_MEM_NAME "/test"
#define SHARED_MEM_SIZE 1024

int main(int argc, char *argv[]) {
    int shm_fd;
    char *mem_ptr;

    // 创建共享内存对象
    shm_fd = shm_open(SHARED_MEM_NAME, O_CREAT | O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        exit(EXIT_FAILURE);
    }

    // 设置共享内存对象的大小
    if (ftruncate(shm_fd, SHARED_MEM_SIZE) == -1) {
        perror("ftruncate");
        exit(EXIT_FAILURE);
    }

    // 映射共享内存对象到进程的虚拟地址空间中
    mem_ptr = (char*)mmap(NULL, SHARED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (mem_ptr == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    // 读写共享内存
    strncpy(mem_ptr, "hello world", SHARED_MEM_SIZE);
    printf("read from shared memory: %s\n", mem_ptr);

    // 解除映射关系
    if (munmap(mem_ptr, SHARED_MEM_SIZE) == -1) {
        perror("munmap");
        exit(EXIT_FAILURE);
    }

    // 删除共享内存对象
    if (shm_unlink(SHARED_MEM_NAME) == -1) {
        perror("shm_unlink");
        exit(EXIT_FAILURE);
    }

    return EXIT_SUCCESS;
}
总结

POSIX共享内存API提供了一种高效的进程间通信方式,它能够通过将数据存储在物理内存中来避免复制,因此速度更快。在使用共享内存时需要注意保护共享数据的一致性和互斥性,避免因并发访问而导致的数据冲突。