1. C++多进程编程基础解析
在Linux/Unix系统下,多进程编程通常从fork()系统调用开始。这个看似简单的函数实际上完成了一系列复杂的操作:
cpp复制#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
perror("fork failed");
exit(EXIT_FAILURE);
}
else if (pid == 0) {
// 子进程执行的代码
printf("Child process PID: %d\n", getpid());
_exit(EXIT_SUCCESS); // 子进程明确退出
}
else {
// 父进程执行的代码
printf("Parent process PID: %d\n", getpid());
wait(NULL); // 等待子进程结束
}
return EXIT_SUCCESS;
}
关键细节:在子进程中应该使用_exit()而非exit(),因为exit()会刷新标准I/O缓冲区,可能导致重复输出。
fork()的工作原理可以这样理解:
- 内核为新进程创建PCB(进程控制块)
- 复制父进程的地址空间
- 复制父进程的文件描述符表
- 设置新的PID和PPID
- 返回两次(父进程返回子进程PID,子进程返回0)
1.1 进程创建的性能考量
虽然fork()采用写时复制(Copy-On-Write)技术优化性能,但在以下场景仍需注意:
- 父进程内存占用过大时,fork()可能较慢
- 频繁创建销毁进程会带来显著开销
- 子进程继承的文件描述符需要谨慎处理
替代方案:
cpp复制// 使用posix_spawn()替代fork()+exec()
#include <spawn.h>
char *argv[] = {"ls", "-l", NULL};
pid_t pid;
posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ);
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 进程间通信机制深度剖析
2.1 管道(Pipe)的进阶用法
匿名管道是最基础的IPC方式,但实际使用时有许多细节需要注意:
cpp复制int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 设置管道非阻塞
int flags = fcntl(pipefd[0], F_GETFL);
fcnt
