1.进程的退出
1.exit
功能:
让进程退出,并刷新缓存区
参数:
status:进程退出的状态
返回值:
缺省
exit -> 刷新缓存区 -> atexit注册的退出函数 -> _exit
2._exit
功能:
让进程退出,不刷新缓存区
参数:
status:进程退出状态
返回值:
缺省
3.atexit
功能:
注册进程退出前执行的函数
参数:
function:函数指针
指向void返回值void参数的函数指针
返回值:
成功返回0
失败返回非0
当程序调用exit或者由main函数执行return时,所有用atexit
注册的退出函数,将会由注册时顺序倒序被调用
多个使用和栈区类似,先进后出,后进先出。
2. 进程空间的回收
wait:
pid_t wait(int *status);
功能:该函数可以阻塞等待任意子进程退出
并回收该进程的状态。
一般用于父进程回收子进程状态。
参数:status 进程退出时候的状态
如果不关心其退出状态一般用NULL表示
如果要回收进程退出状态,则用WEXITSTATUS回收。
返回值:成功 回收的子进程pid
失败 -1;
注意事项:
1.如果所有的子进程都在运行,在阻塞
2.如果一个子进程终止,正在等待的父进程则获得终止状态,获得子进程的状态后,立刻返回。
3.如果没有子进程,则立即出错退出。
waitpid:
pid_t waitpid(pid_t pid, int *status, int options);
功能:回收指定进程的资源
和wait功能相似,比wait更灵活
参数:
pid:
<-1 回收指定进程组内的任意子进程 (-100.等待GID=100的进程组中的任意子进程)
-1 回收任意子进程,组内外
0 回收和当前调用waitpid一个组的所有子进程,组内
> 0 回收指定ID的子进程
status 子进程退出时候的状态,
如果不关注退出状态用NULL;
options 选项:
0 表示回收过程会阻塞等待
WNOHANG 表示非阻塞模式回收资源。
返回值: 成功 返回接收资源的子进程pid
失败 -1
设定为非阻塞且没有回收到子进程返回0
waitpid(0,&status,0) //默认阻塞 ==wait(&status);
waitpid(0,&status,WNOHANG); // 非阻塞方式
这是非阻塞状态进行输出,son pid 与 father pid 同时执行,当son pid被回收后,wait pid输出其pid 。
3.exec族
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,
..., char * const envp[]);
int execv(const char *path, char * argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
功能:
利用进程空间执行另外一段代码
参数:
l:参数以列表形式传递
p:在系统路径下找要执行的代码
e:执行新代码时更新环境变量
v:参数以指针数组形式传递
返回值
成功无法返回
失败返回-1
使用execvp创造dir文件夹。
使用execv和execlp打印ls -l
以及使用exec来创造minishell
目前有一个bug存在,已知:通过fork()来生成父子pid,每当 我们使用一段进程来实现minishell的相关程序,父pid就会重新分成新的父子pid,使用exit(0)回收内存时,会依次回收之前执行次数的执行程序,才可以退出。
解决了 !
因为cd更改路径在子程序中导致系统多次回收,那么,我们将cd放在父程序中进行判断,在此基础上,在fork()之前和循环结尾多重判断exit,此时就可以退出 。