多进程共享内存

一个6进程并发的共享内存的例子,5个子进程对共享内存写入不同数据,第6个进程负责读取数据另外5个进程全部写入的数据。

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

#define SHM_SIZE      1024
#define NUM_PROCESSES 6

// 创建共享内存段
int create_shared_memory()
{
    int shmid;

    // 调用shmget函数创建共享内存段
    shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(1);
    }

    return shmid;
}

// 将共享内存段映射到当前进程的虚拟地址空间
char* attach_shared_memory(int shmid)
{
    char* shmaddr;

    // 调用shmat函数将共享内存段映射到当前进程的虚拟地址空间
    shmaddr = (char*)shmat(shmid, NULL, 0);
    if (shmaddr == (char*)-1) {
        perror("shmat");
        exit(1);
    }

    return shmaddr;
}

// 子进程写入数据到共享内存
void write_data_to_shared_memory(char* shmaddr, const char* data, int process_id)
{
    printf("子进程 %d 开始写入数据...\n", process_id);

    // 计算写入位置
    int offset = (process_id - 1) * 100;

    // 使用memcpy函数将数据写入共享内存
    memcpy(shmaddr + offset, data, strlen(data));

    sleep(1); // 模拟写入过程中的耗时操作

    printf("子进程 %d 写入数据完成。\n", process_id);
}

// 父进程从共享内存读取数据
void read_data_from_shared_memory(char* shmaddr)
{
    printf("父进程开始读取数据...\n");

    // 创建一个缓冲区用于存放读取到的数据
    char buffer[SHM_SIZE];
    memset(buffer, 0, SHM_SIZE);

    // 读取共享内存中的数据并保存到缓冲区
    for (int i = 0; i < NUM_PROCESSES; ++i) {
        int offset = i * 100;
        char* data = shmaddr + offset;
        strcat(buffer, data);
    }

    // 输出读取到的数据
    printf("读取到的数据为:%s\n", buffer);

    printf("父进程读取数据完成。\n");
}

// 解除共享内存映射
void detach_shared_memory(char* shmaddr)
{
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(1);
    }

    printf("共享内存解除映射完成。\n");
}

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

    printf("共享内存段删除成功。\n");
}

int main(void)
{
    pid_t pid;
    int shmid;
    char* shmaddr;

    // 创建共享内存段
    shmid = create_shared_memory();

    // 将共享内存段映射到当前进程的虚拟地址空间
    shmaddr = attach_shared_memory(shmid);

    // 创建五个子进程,每个进程分别写入不同的数据
    int i;
    for (i = 0; i < NUM_PROCESSES - 1; ++i) {
        pid = fork();
        if (pid == -1) {
            perror("fork");
            exit(1);
        } else if (pid == 0) {
            // 调用子函数写入数据到共享内存
            char data[100];
            if (i == 4) {
                sprintf(data, "Data from process %d \n", i + 1);
                write_data_to_shared_memory(shmaddr, data, i + 1);
            } else {
                sprintf(data, "Data from process %d, ", i + 1);
                write_data_to_shared_memory(shmaddr, data, i + 1);
            }

            // 解除共享内存映射并退出子进程
            detach_shared_memory(shmaddr);
            exit(0);
        }
    }

    // 创建第六个子进程,负责读取另外五个进程写入的数据
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(1);
    } else if (pid == 0) {
        // 调用子函数读取数据
        read_data_from_shared_memory(shmaddr);

        // 解除共享内存映射并退出子进程
        detach_shared_memory(shmaddr);
        exit(0);
    }

    // 等待所有子进程完成
    for (i = 0; i < NUM_PROCESSES; ++i) {
        wait(NULL);
    }

    // 删除共享内存段
    remove_shared_memory(shmid);

    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神奇的小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值