3 changed files with 281 additions and 184 deletions
@ -0,0 +1,134 @@ |
|||
# 共享内存 + 有名管道 实现无亲缘关系进程通信 |
|||
|
|||
## 问题概述 |
|||
原有的`shm_pc.c`是父子进程通信模型,使用匿名管道进行同步。需要将其修改为两个无亲缘关系进程间的通信模型,分别为生产者进程和消费者进程。 |
|||
|
|||
## 解决方案 |
|||
|
|||
### 1. 进程间通信方式选择 |
|||
- **共享内存**:用于高效传输大量数据(任务队列) |
|||
- **有名管道(FIFO)**:用于无亲缘关系进程间的同步信号传递 |
|||
- **信号量**:用于共享内存的互斥访问和任务队列的同步 |
|||
|
|||
### 2. 核心实现 |
|||
|
|||
#### 文件结构 |
|||
``` |
|||
1_shared_memory/ |
|||
├── shm_comm/ |
|||
│ ├── shm_comm_a.c # 生产者进程 |
|||
│ └── shm_comm_b.c # 消费者进程 |
|||
``` |
|||
|
|||
#### 主要功能 |
|||
|
|||
##### shm_comm_a.c (生产者) |
|||
- 创建共享内存(包含环形任务队列) |
|||
- 创建有名管道用于同步 |
|||
- 向共享内存提交5个测试任务 |
|||
- 发送同步信号通知消费者进程 |
|||
- 等待消费者处理完成后销毁共享内存 |
|||
|
|||
##### shm_comm_b.c (消费者) |
|||
- 等待并打开有名管道 |
|||
- 接收生产者的同步信号 |
|||
- 挂载共享内存 |
|||
- 创建线程池处理任务 |
|||
- 完成所有任务后退出 |
|||
|
|||
### 3. 关键技术点 |
|||
|
|||
#### 环形任务队列 |
|||
```c |
|||
// 共享内存核心结构体 |
|||
typedef struct { |
|||
Task task_queue[MAX_TASK]; // 共享任务队列 |
|||
int front; // 队列头 |
|||
int rear; // 队列尾 |
|||
int sem_id; // 信号量集ID |
|||
} SharedMem; |
|||
|
|||
// 入队操作(生产者) |
|||
shm->rear = (shm->rear + 1) % MAX_TASK; |
|||
shm->task_queue[shm->rear] = task; |
|||
|
|||
// 出队操作(消费者) |
|||
Task task = shm->task_queue[shm->front]; |
|||
shm->front = (shm->front + 1) % MAX_TASK; |
|||
``` |
|||
|
|||
#### 信号量机制 |
|||
- **互斥信号量**(索引0):保护共享内存的互斥访问 |
|||
- **空信号量**(索引1):表示队列中的任务数量,初始值为0 |
|||
- **满信号量**(索引2):表示队列中的空闲位置数量,初始值为MAX_TASK |
|||
|
|||
#### 有名管道同步 |
|||
```c |
|||
// 生产者创建有名管道 |
|||
mkfifo(FIFO_PATH, 0666); |
|||
|
|||
// 生产者发送同步信号 |
|||
int fifo_fd = open(FIFO_PATH, O_WRONLY); |
|||
write(fifo_fd, "ok", 2); |
|||
|
|||
// 消费者接收同步信号 |
|||
int fifo_fd = open(FIFO_PATH, O_RDONLY); |
|||
read(fifo_fd, buf, 2); |
|||
``` |
|||
|
|||
### 4. 编译和运行 |
|||
|
|||
#### 编译命令 |
|||
```bash |
|||
gcc -o shm_comm_a shm_comm_a.c -lpthread |
|||
gcc -o shm_comm_b shm_comm_b.c -lpthread |
|||
``` |
|||
|
|||
#### 运行步骤 |
|||
1. 启动生产者进程: |
|||
```bash |
|||
./shm_comm_a |
|||
``` |
|||
|
|||
2. 启动消费者进程: |
|||
```bash |
|||
./shm_comm_b |
|||
``` |
|||
|
|||
### 5. 测试结果 |
|||
|
|||
生产者进程输出: |
|||
``` |
|||
[生产者进程] 启动,创建共享内存... |
|||
[生产者进程] 已发送同步信号:ok |
|||
[提交进程] 提交任务1:测试任务_1 |
|||
[提交进程] 提交任务2:测试任务_2 |
|||
[提交进程] 提交任务3:测试任务_3 |
|||
[提交进程] 提交任务4:测试任务_4 |
|||
[提交进程] 提交任务5:测试任务_5 |
|||
[生产者进程] 退出 |
|||
``` |
|||
|
|||
消费者进程输出: |
|||
``` |
|||
[消费者进程] 收到生产者同步信号:ok |
|||
[消费者进程] 启动,创建线程池... |
|||
[线程140408006018816] 取出任务1:测试任务_1 |
|||
[线程140407997626112] 取出任务2:测试任务_2 |
|||
[线程140407989233408] 取出任务3:测试任务_3 |
|||
[线程140407980840704] 取出任务4:测试任务_4 |
|||
[线程140408006018816] 取出任务5:测试任务_5 |
|||
[消费者进程] 停止线程池... |
|||
[消费者进程] 退出 |
|||
``` |
|||
|
|||
## 总结 |
|||
|
|||
本实现成功将父子进程通信模型修改为无亲缘关系进程通信: |
|||
1. 使用**有名管道**替代匿名管道实现进程同步 |
|||
2. 保持了**共享内存**的高效数据传输特性 |
|||
3. 维护了**环形任务队列**的高效空间利用 |
|||
4. 通过**信号量**确保了共享资源的安全访问 |
|||
5. 实现了**线程池**的多任务并行处理 |
|||
|
|||
测试结果表明,两个无亲缘关系的进程能够稳定通信并正确处理任务。 |
|||
Loading…
Reference in new issue