#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define CHILD_PROCESS_NUM 3
sem_t *semaphores[CHILD_PROCESS_NUM];
void child_process(int index) {
while (1) {
sem_wait(semaphores[index]);
// 模拟处理任务
printf("Child process %d is handling a task.\n", index);
sleep(1);
}
}
int main() {
pid_t pids[CHILD_PROCESS_NUM];
for (int i = 0; i < CHILD_PROCESS_NUM; i++) {
char sem_name[20];
snprintf(sem_name, sizeof(sem_name), "/sem_%d", i);
semaphores[i] = sem_open(sem_name, O_CREAT, 0666, 0);
if (semaphores[i] == SEM_FAILED) {
perror("sem_open");
return 1;
}
pids[i] = fork();
if (pids[i] == -1) {
perror("fork");
return 1;
} else if (pids[i] == 0) {
child_process(i);
exit(0);
}
}
// 模拟产生任务
for (int i = 0; i < 10; i++) {
int random_index = rand() % CHILD_PROCESS_NUM;
sem_post(semaphores[random_index]);
}
for (int i = 0; i < CHILD_PROCESS_NUM; i++) {
waitpid(pids[i], NULL, 0);
sem_close(semaphores[i]);
char sem_name[20];
snprintf(sem_name, sizeof(sem_name), "/sem_%d", i);
sem_unlink(sem_name);
}
return 0;
}
关键部分作用说明
- 信号量初始化:
- 使用
sem_open
函数创建并初始化了CHILD_PROCESS_NUM
个信号量,每个信号量对应一个子进程,初始值为0。这些信号量用于控制子进程对任务的处理,通过信号量来实现任务的分配。
- 子进程创建:
- 使用
fork
函数创建了CHILD_PROCESS_NUM
个子进程,每个子进程进入child_process
函数。
- 子进程处理任务:
- 在
child_process
函数中,子进程通过sem_wait
等待对应的信号量,当信号量的值大于0时,子进程获取信号量并开始处理任务,模拟处理任务的部分通过printf
和sleep
实现。
- 任务分配:
- 在主进程中,通过
rand() % CHILD_PROCESS_NUM
随机选择一个子进程对应的信号量,然后使用sem_post
增加该信号量的值,从而通知对应的子进程有新任务。
- 清理资源:
- 主进程通过
waitpid
等待所有子进程结束,然后使用sem_close
关闭信号量,使用sem_unlink
删除信号量,以清理资源。