如何在FreeBSD中用C代码限制N个并行子进程处理文件?
FreeBSD下限制N个并行子进程处理文件的C实现
核心逻辑
要限制同时运行的子进程数不超过N,核心是让父进程在子进程数达到上限时,等待任意一个子进程结束后再创建新进程,以此维持进程池的大小稳定。
完整代码实现
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <errno.h> // 子进程处理文件的函数,可替换为实际业务逻辑 void process_file(const char *filename) { printf("子进程[%d]正在处理文件: %s\n", getpid(), filename); sleep(2); // 模拟处理耗时操作 printf("子进程[%d]完成文件: %s\n", getpid(), filename); } int main(int argc, char *argv[]) { int max_processes; int active_processes = 0; pid_t pid; int status; // 参数合法性校验 if (argc < 3) { fprintf(stderr, "用法: %s <并行数N> <文件1> <文件2> ...\n", argv[0]); exit(EXIT_FAILURE); } // 解析并行数N max_processes = atoi(argv[1]); if (max_processes <= 0) { fprintf(stderr, "错误: 并行数N必须是正整数\n"); exit(EXIT_FAILURE); } // 遍历所有待处理文件 for (int i = 2; i < argc; i++) { // 活跃进程数达上限时,等待任意子进程退出 while (active_processes >= max_processes) { pid = waitpid(-1, &status, 0); if (pid == -1) { if (errno == ECHILD) { active_processes = 0; break; } else { perror("waitpid错误"); exit(EXIT_FAILURE); } } active_processes--; } // fork前刷新所有缓冲区,避免父子进程重复输出 fflush(NULL); pid = fork(); if (pid < 0) { perror("fork错误"); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程处理文件后直接退出,不执行父进程后续逻辑 process_file(argv[i]); exit(EXIT_SUCCESS); } else { // 父进程更新活跃进程计数 active_processes++; } } // 等待剩余所有子进程退出 while (active_processes > 0) { waitpid(-1, &status, 0); active_processes--; } printf("所有文件处理完成\n"); return EXIT_SUCCESS; }
关键细节说明
- 进程数控制:用
active_processes变量跟踪当前运行的子进程数量,达到上限时通过waitpid(-1, &status, 0)等待任意子进程结束,再创建新进程 - 缓冲区处理:fork前调用
fflush(NULL)刷新所有输出缓冲区,避免父子进程的缓存内容重复打印 - 子进程退出:子进程处理完文件后必须调用
exit,防止子进程继续执行父进程的循环逻辑 - 收尾操作:所有文件分配完成后,父进程需等待剩余子进程全部退出再结束程序
内容的提问来源于stack exchange,提问作者Henry FXP
相关产品推荐
相关产品推荐

