个人博客:https://alive0103.github.io/
代码在GitHub:https://github.com/Alive0103/XDU-CS-lab
能点个Star就更好了,欢迎来逛逛哇~❣
主播写的刚够满足基本功能,多有不足,仅供参考,还请提PR指正,很高兴能帮到你
一、 实验内容
在linux平台上实现1个父进程、10个以上子进程,其中一些子进程具有特定任务(如完成:显示、计算、报警等),各进程之间利用管道、信号灯和共享内存实现数据传送。
实验目的
掌握Linux平台下进程创建与控制方法
理解管道(Pipe)、共享内存(Shared Memory)和信号量(Semaphore)三种IPC机制
实现多进程协作系统架构设计
验证进程间数据同步与互斥控制的正确性
实验原理
进程架构设计
graph TD
Parent[父进程] -->|管道| Calc[计算进程x4]
Parent -->|共享内存| Display[显示进程x3]
Calc -->|共享内存| Alert[报警进程x3]
Alert -->|管道| Parent
IPC机制对比
实验步骤
环境搭建
# 创建实验目录
mkdir ~/ipc-lab && cd ~/ipc-lab
# 安装开发工具
sudo apt install -y g++ make
# 验证内核支持
cat /proc/sys/kernel/shmmax # 显示共享内存最大尺寸
关键代码实现
进程创建模块
for (int i = 0; i < CHILD_NUM; ++i) {
pid_t pid = fork();
if (pid == 0) {
// 子进程分工控制
if (i < 4) calc_worker();
else if (i < 7) display_worker();
else alert_worker();
exit(0);
}
}
共享内存控制模块
// 创建共享内存
int shmid = shmget(key, sizeof(SharedData), IPC_CREAT|0666);
// 内存映射
SharedData* shared = (SharedData*)shmat(shmid, NULL, 0);
// 资源释放
shmdt(shared);
shmctl(shmid, IPC_RMID, NULL);
完整代码
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <cstring>
#include <fcntl.h>
#define THRESHOLD 100
struct SharedData {
int calculation;
bool alarm_status;
};
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void P(int semid) {
struct sembuf op = {0, -1, SEM_UNDO};
semop(semid, &op, 1);
}
void V(int semid) {
struct sembuf op = {0, 1, SEM_UNDO};
semop(semid, &op, 1);
}
int main() {
// 创建IPC key
key_t key = ftok("keyfile", 65);
// 共享内存初始化
int shmid = shmget(key, sizeof(SharedData), IPC_CREAT|0666);
SharedData* shared = static_cast<SharedData*>(shmat(shmid, nullptr, 0));
shared->calculation = 0;
shared->alarm_status = false;
// 信号量初始化
int semid = semget(key, 1, IPC_CREAT|0666);
union semun arg;
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
// 创建通信管道
int data_pipe[2], alert_pipe[2];
pipe(data_pipe);
pipe(alert_pipe);
const int CHILD_NUM = 10;
for (int i = 0; i < CHILD_NUM; ++i) {
pid_t pid = fork();
if (pid == 0) {
// 计算进程 (0-3)
if (i < 4) {
close(data_pipe[1]); // 关闭写端
int input;
while (read(data_pipe[0], &input, sizeof(input)) > 0) {
P(semid);
shared->calculation = input * 2;
V(semid);
}
exit(0);
}
// 显示进程 (4-6)
else if (i < 7) {
while (true) {
P(semid);
std::cout << "Current Value: " << shared->calculation
<< "\tAlarm: " << (shared->alarm_status ? "TRIGGERED" : "NORMAL")
<< std::endl;
V(semid);
sleep(1);
}
}
// 报警进程 (7-9)
else {
close(alert_pipe[0]); // 关闭读端
while (true) {
P(semid);
if (shared->calculation > THRESHOLD && !shared->alarm_status) {
shared->alarm_status = true;
const char* msg = "VALUE EXCEEDED THRESHOLD!";
write(alert_pipe[1], msg, strlen(msg)+1);
} else if (shared->calculation <= THRESHOLD) {
shared->alarm_status = false;
}
V(semid);
sleep(1);
}
}
}
}
// 父进程逻辑
close(data_pipe[0]);
close(alert_pipe[1]);
// 发送测试数据
for (int i = 1; i <= 10; ++i) {
int val = i * 20;
write(data_pipe[1], &val, sizeof(val));
sleep(2);
}
// 接收报警信息
char alert_msg[256];
while (read(alert_pipe[0], alert_msg, sizeof(alert_msg)) > 0) {
std::cout << "\n[ALERT] " << alert_msg << std::endl;
}
// 清理资源
wait(nullptr);
shmdt(shared);
shmctl(shmid, IPC_RMID, nullptr);
semctl(semid, 0, IPC_RMID);
close(data_pipe[1]);
close(alert_pipe[0]);
return 0;
}