一.fork函数中父进程与子进程之间的文件共享
进程的执行:
1.举例 fork (//子承父业)
复制父进程 和 父进程做同样任务 。
2.子进程创建好之后 fork+exec 函数组 //独立创业
子进程有自己独立任务要做。
shell 程序
bash(4433)
|
fork()
/ \
bash bash + exec(a.out) --->a.out
二.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[]);
1.l带l vs 带 v
int execl (const char *path, const char *arg, ...); //list
int execv (const char *path, char *const argv[]);//vector ---
功能:
执行一个文件 (可执行文件 a.out / 1.sh )
text|data|bss|堆 栈|环境变量及命令行参数 + pcb
用新进程的 镜像 替换 调用进程的 镜像
参数:path 要执行的文件的路径(包含可执行文件的名字)
arg 表示 可执行文件的文件名
... 可变参数
ls -l / 最后写一个NULL 表示结束
execl("/bin/ls","ls","-l","/",NULL);
区别:
在于,参数传递的方式不同,
l --- list ---参数逐个列举
eg:
execl("/bin/ls","ls","-l","/",NULL);
v ---vector --- 参数组织成 指针数组的形式
eg:
char *const arg[] = {"ls","-l","/",NULL};
execv("/bin/ls",arg);
2.p vs e
int execl e (const char *path, const char *arg,..., char * const envp[]);
int execvp e(const char *file, char *const argv[] , char * const envp[]);
p --- path ->PATH (环境变量 --- 都是可执行文件的路径)
带p 表示可执行文件的寻找方式,是从系统的环境变量PATH中的路径下面去找
带e 表示的是可以给要执行的 新程序 传递需要的 环境变量
extern char **environ; //系统的环境变量信息 的指针数组的首地址, [ ] //字符串的的 首地址
注意:
路径加文件名
1.excle
带l的默认会搜索,当前路径下。
2.带p的只搜索
只搜索PATH系统环境变量
二.进程的终止
1.exit 库函数
退出状态,终止的进程会通知父进程,自己使如何终止的。
如果是正常结束(终止),则由exit传入的参数。
如果是异常终止,则有内核通知异常终止原因的状态。
任何情况下,父进程都能使用wait,waitpid获得这个状态,以及资源的回收。
void exit(int status)
exit(1);
功能:
让进程退出,并刷新缓存区
参数:
status:进程退出的状态
return 当该关键字出现在main函数中时候可以结束进程
如果在其他函数中则表示结束该函数。
exit -> 刷新缓存区 -> atexit注册的退出函数 -> _exit
2.exit 系统调用
void _exit(int status);
功能:
让进程退出,不刷新缓存区
参数:
status:进程退出状态
3.atexit
int atexit(void (*function)(void));
功能:
注册进程退出前执行的函数
参数:
function:函数指针
指向void返回值void参数的函数指针
返回值:
成功返回0
失败返回非0
当程序调用exit或者由main函数执行return时,所有用atexit
注册的退出函数,将会由注册时顺序倒序被调用
注意:
a. 是exit函数调用时,会调atexit函数
_exit函数调用时,不会调到atexit
b. atexit 程序正常结束
(1).main 返回 //exit
(2).exit()
c.atexit函数 可以多次注册
d.最后"退出清理函数"的调用顺序,与注册顺序相反。