启动进程
system
用于在代码中执行 shell 命令。
#include <stdlib.h>
int system(const char *command);类型:库函数
线程安全:是
参数:
返回值:
成功:
失败:-1 并设置 errno
system 内部是调用 fork 来创建子进程,子进程来执行shell命令。
使用示例:
exec
用于执行一个程序,新程序会取代旧程序。
exec 有7个函数:
#include <unistd.h>
int execl(const char *pathname, const char *arg, ...
/*, (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/*, (char *) NULL */);
int execle(const char *pathname, const char *arg, ...
/*, (char *) NULL, char *const envp[] */);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
int execve(const char *pathname, char *const _Nullable argv[],
char *const _Nullable envp[]);
其中,只有 execve 为系统调用,其用函数都是在这上面封装的。
参数:
pathname:路径
file:文件名
arg:参数序列,使用,分隔
argv:参数列表
envp:环境变量列表
返回值:
成功:不会返回,因为调用进程的实体(代码段、数据段、堆栈等)被新进程所取代了。
失败:-1 并设置 errno
创建子进程
用于创建子进程。
fork
#include <unistd.h>
pid_t fork(void);类型:系统调用
线程安全:是
参数:
返回值:
成功:父进程中返回子进程 ID,子进程中返回 0
失败:-1 并设置 errno
获取当前进程
父进程:
子进程:0
父子进程共享代码段,不共享其它的。
父子进程各从 fork 函数之后执行代码。
子进程复制父进程的文件描述符,但不复制文件锁。
子进程的未处理的闹钟定时器被清除,子进程不继承父进程的未决信号集。
vfork
#include <unistd.h>
pid_t vfork(void);类型:系统调用
线程安全:是
参数:
返回值:
成功:
失败:-1 并设置 errno
fork 和 vfork 的区别
fork 复制父进程的数据段,vfork 不完全复制。
阻塞父进程:
fork 不阻塞父进程,所以运行顺序不确定。
vfork 阻塞父进程(直到子进程退出或执行exec()),运行顺序确定,子进程先运行,父进程再运行。
使用场景:
fork:
vfork:
vfrok 的使用场景是调用exec的函数,
等待进程
类型:
线程安全:是
参数:
返回值:
成功:返回
失败:-1 并设置 errno
终止进程
类型:
线程安全:是
参数:
返回值:
成功:
失败:-1 并设置 errno