一个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;
}