1.exec族函数的区别
int exec l(const char *path, const char *arg, ...);
int exec l p(const char *file, const char *arg, ...);
int exec l e(const char *path, const char *arg,..., char * const envp[]);
int exec v(const char *path, char *const argv[]);
int exec v p(const char *file, char *const argv[]);
int exec v pe(const char *file, char *const argv[], char *const envp[]);
路径 vs 文件名:
使用完整路径(path
)的函数(如execl
、execv
、execle
、execve
)需要指定可执行文件的
完整路径。
使用文件名(file
)的函数(如execlp
、execvp
)会根据PATH
环境变量中指定的目录来搜索
可执行文件。
参数传递方式:
l
(list)后缀的函数(如execl
、execlp
、execle
)要求将命令行参数逐个列出,并以NULL
作
为结束标志。
v
(vector)后缀的函数(如execv
、execvp
、execve
)要求将命令行参数组织成一个字符指
针数组(char *const argv[]
),并将这个数组的指针传递给函数。
环境变量:
大多数exec
函数使用调用进程继承的环境变量。以e
(environment)结尾的函数(如
execle
、execve
)允许显式地传递一个新的环境变量数组给新程序。
真正的系统调用:
execve
是唯一真正的系统调用。其他exec
函数都是库函数,它们最终都会调用execve
。
2. exit
库函数
功能:exit
函数用于终止当前进程,并向父进程返回一个整数状态码。同时,它会刷新所有
输出流(如标准输出 stdout
)的缓冲区,并调用通过 atexit
函数注册的所有清理函数(按注册顺
序的逆序调用)。
参数:int status
,表示进程的退出状态。通常,EXIT_SUCCESS
(定义为0)表示成功,
而 EXIT_FAILURE
(通常定义为1,但具体值取决于系统)表示某种形式的失败。
返回值:exit
函数没有返回值,因为一旦调用,程序就会终止。
3. _exit
系统调用
功能:_exit
是一个系统调用,用于立即终止当前进程,但与 exit
不同,它不会刷新输出流
的缓冲区,也不会调用 atexit
注册的清理函数。
参数:与 exit
相同,int status
表示进程的退出状态。
返回值:同样,_exit
也没有返回值,因为程序会立即终止。
4. atexit
功能:atexit
函数用于注册一个函数,该函数将在程序正常终止(即调用 exit
或从 main
函
数返回)时自动调用。这可以用于执行必要的清理操作,如释放资源、关闭文件等。
参数:void (*function)(void)
,一个指向函数的指针,该函数没有参数并返回 void
。
返回值:成功时返回0,失败时返回非0值。通常,atexit
的失败很少见,因为它只是向一个
列表中添加一个函数指针。
5.创建 进程 (fork)
1.创建之后,父子进程各自拥有4g独立的内存空间
2.各自拥有自己的相关的程序的各个段 数据段,所以,各自之间对数据的改变,不会相互影响
3.子进程会继承父进程已打开的文件描述符
若,fork之前打开文件,父子进程操作同一个文件,相互间有影响
若,fork之后打开文件,父子进程操作同一个文件,但是,因为各自拥有自己的 "文件表项",
所以,各自按照自己的逻辑改变文件
6.进程的终止:8种情况
1)main 中 return
2)exit() //库函数
c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。
注册清理函数(atexit)。
3)_exit,_Exit 会关闭所有的已经打开的文件,不执行清理函数。 //系统调用
4) 主线程退出
5)主线程调用pthread_exit
异常终止:
6)abort()
7)signal kill pid
8) 最后一个线程被pthread_cancle