在 Linux 系统中,可以通过以下系统调用来创建新进程:
1. `fork()`
- `fork()` 是最常用的系统调用,用于创建一个新进程。
- 调用 `fork()` 时,操作系统会为新进程创建一个新的地址空间,并复制父进程的上下文。
- 返回值:
- 子进程中返回 0。
- 父进程中返回子进程的 PID(进程 ID)。
- 父子进程会从 `fork()` 调用之后的代码处继续执行,但可能顺序不同(调度由操作系统决定)。
2. `vfork()`
- 类似于 `fork()`,但 `vfork()` 在性能上进行了优化。
- 新进程共享父进程的地址空间,直到调用 `exec()` 或 `_exit()` 之前不能修改共享资源。
- 常用于父进程立即调用 `exec()` 的场景,但因为容易出错(共享地址空间),不推荐使用。
3. `clone()`
- 是更底层、更灵活的系统调用,用于创建新进程或线程。
- 允许指定共享父进程的某些资源(如内存、文件描述符、信号处理等)。
- `clone()` 是许多线程库(如 `pthread`)的基础。
4. `posix_spawn()`
- `posix_spawn()` 是 POSIX 标准接口,用于创建新进程并执行新程序。
- 内部可能使用 `fork()` 和 `exec()` 的组合。
- 优势:提供了更高层次的封装,减少编程复杂性。
5. `exec` 系列函数
- 严格来说,`exec` 系列(如 `execl()`、`execv()` 等)并不是创建新进程,而是用于替换当前进程的地址空间以加载新程序。
- 通常与 `fork()` 配合使用。
6. `system()`
- `system()` 是一个高级函数,用于执行 shell 命令。
- 内部实际上是调用了 `fork()` 和 `exec()`。
总结
- 一般情况下,`fork()` 是最常用的创建新进程的方法。
- 如果需要更精细的控制,可以使用 `clone()`。
- 需要更高层次的封装时,可以考虑 `posix_spawn()`。