fork()
系统调用创建子进程,父进程通过wait()
或waitpid()
回收资源并防止僵尸进程,子进程可配合exec()
族函数执行新程序。在Linux环境下编写多进程程序是系统编程的核心技能之一,它允许程序同时执行多个任务,充分利用多核CPU资源,以下是详细的技术实现指南:
多进程编程基础
核心系统调用:
-
fork()
- 创建当前进程的副本(子进程),父进程返回子进程PID,子进程返回0
- 代码示例:
pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(1); } else if (pid == 0) { // 子进程代码 printf("Child PID: %dn", getpid()); } else { // 父进程代码 printf("Parent PID: %dn", getpid()); }
-
exec()族函数
- 替换当前进程映像(如
execlp()
执行新程序)execlp("/bin/ls", "ls", "-l", NULL); // 子进程中替换为ls命令
- 替换当前进程映像(如
-
wait() / waitpid()
- 父进程阻塞等待子进程退出,避免僵尸进程
int status; waitpid(pid, &status, 0); // 等待特定子进程
- 父进程阻塞等待子进程退出,避免僵尸进程
完整多进程示例
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("Fork error"); return 1; } if (pid == 0) { // 子进程 printf("[Child] PID: %dn", getpid()); execlp("/bin/date", "date", NULL); // 替换为date命令 } else { // 父进程 printf("[Parent] PID: %dn", getpid()); wait(NULL); // 等待子进程结束 printf("Child process completedn"); } return 0; }
运行效果:
[Parent] PID: 1234
[Child] PID: 1235
Tue Jun 18 10:30:00 CST 2025
Child process completed
关键问题与解决方案
-
僵尸进程处理
- 成因:子进程退出后父进程未调用
wait()
- 解决:
- 父进程调用
wait()
回收资源 - 使用信号处理:
signal(SIGCHLD, SIG_IGN)
自动回收
- 父进程调用
- 成因:子进程退出后父进程未调用
-
孤儿进程
- 父进程先退出时,子进程由init进程(PID=1)接管
- 系统自动回收,通常无需特殊处理
-
进程间通信(IPC)
| 方式 | 适用场景 | 关键函数 |
|—————|—————————-|———————–|
| 管道(Pipe) | 父子进程单向通信 |pipe()
,dup2()
|
| 共享内存 | 高速大数据量交换 |shmget()
,shmat()
|
| 消息队列 | 结构化数据传递 |msgget()
,msgsnd()
|
| 信号量 | 进程同步控制 |semget()
,semop()
|
最佳实践
-
错误检查
所有系统调用后检查返回值(如fork()
,exec()
的返回值) -
资源管理
- 文件描述符:fork后关闭未使用的描述符
- 内存:exec前释放非共享内存
-
并发控制
- 限制子进程数量(例如使用进程池)
- 避免
fork炸弹
:setrlimit(RLIMIT_NPROC, ...)
设置进程数上限
-
现代替代方案
- CPU密集型任务:考虑多线程(pthread)
- I/O密集型任务:异步I/O(epoll)或协程
应用场景
- Web服务器(Nginx:Master/Worker多进程模型)
- 批量数据处理(并行计算任务)
- 安全隔离(Chrome浏览器:多进程沙箱)
引用说明基于Linux手册页(man7.org)、《Unix环境高级编程》(Addison-Wesley)及内核源码分析,技术细节遵循POSIX标准,已在Linux 5.x内核及GCC 11环境下验证。
通过合理运用多进程模型,开发者可以构建高并发、高可靠的应用系统,重点需关注进程生命周期管理和IPC机制,避免资源泄漏,实际开发中建议结合性能分析工具(如strace, perf)进行调优。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/39208.html