linux

Linux进程通信:共享内存实现方法

小樊
47
2025-08-31 04:40:05
栏目: 智能运维

在Linux中,共享内存是一种高效的进程间通信(IPC)机制,它允许多个进程访问同一块物理内存。以下是使用共享内存进行进程通信的几种常见方法:

1. POSIX共享内存

POSIX共享内存是基于POSIX标准的,提供了跨平台的共享内存接口。

创建共享内存

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

int main() {
    int shm_fd;
    void *ptr;

    // 创建或打开共享内存对象
    shm_fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        return 1;
    }

    // 设置共享内存大小
    if (ftruncate(shm_fd, 4096) == -1) {
        perror("ftruncate");
        return 1;
    }

    // 映射共享内存到进程地址空间
    ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (ptr == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 使用共享内存
    sprintf((char *)ptr, "Hello, Shared Memory!");

    // 解除映射
    if (munmap(ptr, 4096) == -1) {
        perror("munmap");
        return 1;
    }

    // 关闭共享内存对象
    close(shm_fd);

    // 删除共享内存对象
    shm_unlink("/my_shm");

    return 0;
}

访问共享内存

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

int main() {
    int shm_fd;
    void *ptr;

    // 打开共享内存对象
    shm_fd = shm_open("/my_shm", O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        return 1;
    }

    // 映射共享内存到进程地址空间
    ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (ptr == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 使用共享内存
    printf("Shared Memory Content: %s\n", (char *)ptr);

    // 解除映射
    if (munmap(ptr, 4096) == -1) {
        perror("munmap");
        return 1;
    }

    // 关闭共享内存对象
    close(shm_fd);

    return 0;
}

2. System V共享内存

System V共享内存是基于System V IPC机制的,提供了更底层的共享内存接口。

创建共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid;
    char *str = "Hello world!";

    // 创建共享内存段
    shmid = shmget(key, sizeof(str), IPC_CREAT | 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(1);
    }

    // 将共享内存段附加到进程地址空间
    char *ptr = (char *)shmat(shmid, NULL, 0);
    if (ptr == (char *)(-1)) {
        perror("shmat");
        exit(1);
    }

    // 复制数据到共享内存
    strcpy(ptr, str);

    // 分离共享内存段
    if (shmdt(ptr) == -1) {
        perror("shmdt");
        exit(1);
    }

    printf("Shared Memory Content: %s\n", ptr);

    // 删除共享内存段
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(1);
    }

    return 0;
}

访问共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid;
    char *str;

    // 获取共享内存段
    shmid = shmget(key, sizeof(str), 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(1);
    }

    // 将共享内存段附加到进程地址空间
    str = (char *)shmat(shmid, NULL, 0);
    if (str == (char *)(-1)) {
        perror("shmat");
        exit(1);
    }

    // 访问共享内存
    printf("Shared Memory Content: %s\n", str);

    // 分离共享内存段
    if (shmdt(str) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

总结

选择哪种方法取决于具体的需求和系统支持。通常情况下,推荐使用POSIX共享内存,因为它更易于使用和维护。

0
看了该问题的人还看了