进程资源的回收
进程终止时,需要将进程占用的资源回收,父进程负责回收子进程的资源
wait(2)
#include
#include
pid_t wait(int *status);
功能:阻塞等待子进程,挂起当前进程的执行,直到子进程终止
参数:
staus将子进程的状态码存储到status指定的地址空间
这个整数可以用以下宏来检测
WIFEXITED(status)子进程正常终止,返回值为真
WEXITSTATUS(status)返回子进程的退出状态码,这个宏只有在WIFEXITED为真时才能使用
WIFSIGNALED(status)如果子进程被信号终止返回真
WIERMSIG(status)返回导致子进程终止的信号编号,这个宏只能在WIFSIGNALED返回真时使用
返回值:
成功:返回终止了子进程的PID
失败:返回-1,errno被设置
pid_t wait(pid_t pid,int *status,int option);
功能:等待指定的PID子进程的状态改变
参数:
pid:指定具体的子进程
-1:等待任意子进程
>0:指定pid
0:等待和当前进程同一进程组的子进程
<-1:等待pid绝对值的子进程
status:同wait
options:
WNOHANG:没有子进程终止立即返回
0:阻塞等待子进程终止
返回值:
成功:返回状态改变的子进程的PID
失败:返回-1,errno被设置
用代码看一下进程的回收
注:
僵尸进程:进程已经终止,资源没有被回收
孤儿进程:父进程被终止,子进程还在,这种情况下,子进程会被过继给另外一个进程
进程映射的更新exec(3)家族函数
更新进程映像:父进程fork子进程时,子进程继承父进程的PCB,进程的PCB中包含文件描述符和进程的映像,所以子进程这时与父进程的PCB完全一样,不便于子进程扩展,于是在进程空间装入新的进程映像替换从父进程继承下来的映像
execve(2)
#include
int execve(const char*filename,char*const argv[ ],char*const envp[ ]);
功能:执行程序
参数:
fliname:指定了要执行的文件名字,必须是二进制文件或者脚本文件
argv:字符串数组,传递给main函数的参数,习惯上是第一个可执行文件的名字
envp:环境变量传递给新的可执行程序,
argv和envp必须以NULL结尾
返回值:
成功:不返回
失败:返回-1,errno被设置
其他exec函数:
相对于execve进行理解即可
exec:代表执行
l:代表list(列表)
p:代表PATH环境变量,须知道要加载的可执行程序的所在路径,有p回到环境变量PATH指定路径中找可执行程序,无p必须指定可执行文件的所在路径
e:有e用户指定环境变量传递给新的可执行程序,无e代表从父进程继承环境变量
v:代表vector向量表
进行当前进程的环境变量的声明,可以使用它查看当前进程的环境变量
extern char ** environ
代码实现:
改变子进程环境变量:
程序中如何对环境变量进行操作?
getenv(3)、setenv(3)、unsetenv(3)、clearenv(3)
#include
char*getenv(const char *name);
功能:获取环境变量name的值
参数:
name:指定了要找的环境变量
返回值:
找不到返回NULL
找到返回name变量值的首地址
int setenv(const char*name,const char*value,int overwitre);
功能:改变或增加一个环境变量的值
参数:
name:指环境变量名字
value:指定变量的值
overwrite:0 不改变原值
非0 使用value替代原来的值
int unsetenv(const char*name);
功能:删除环境变量
参数:
name:指环境变量名字
返回值:同上
int clearenv(void)
功能:清除所有的环境变量,将environ设为NULL
返回值:
成功返回0
失败返回非0
使用时需要声明一下extern char **environ
守护进程:
1. 特点:守护进程是后台进程;生命周期比较长,从系统启动时开启,系统关闭时结束;它是脱离控制终端且周期执行的进程。
2. 步骤:
①创建子进程,父进程退出
让子进程变成孤儿进程,成为后台进程;fork
②在子进程中创建新回话
让子进程成为会话组组长,为了让子进程完全脱离终端;setsid()
③改变进程运行路径为根目录
原因进程运行的路径不能被删除或卸载;chdir()
④重设文件权限掩码
目的:增大进程创建文件时权限,提高灵活性;umask()
⑤关闭文件描述符
将不需要的文件关闭;close()