进程的回收
子进程结束时由父进程回收
孤儿进程由init进程回收
若没有及时回收会出现僵尸进程
进程回收 – wait
#include <unistd.h>
pid_t wait(int *status);
#include <unistd.h> pid_t wait(int *status);
成功时返回回收的子进程的进程号;失败时返回EOF
若子进程没有结束,父进程一直阻塞
若有多个子进程,哪个先结束就先回收
status 指定保存子进程返回值和结束方式的地址
status为NULL表示直接释放子进程PCB,不接收返回值
相关示例在/study_qianrushi/5.proc/5.1base/wait.c
进程回收 – waitpid
#include <unistd.h> pid_t waitpid(pid_t pid, int *status, int option);
成功时返回回收的子进程的pid或0;失败时返回EOF
pid可用于指定回收哪个子进程或任意子进程
status指定用于保存子进程返回值和结束方式的地址
option指定回收方式,0 或 WNOHANG
waitpid(pid, &status, 0); waitpid(pid, &status, WNOHANG); waitpid(-1, &status, 0); waitpid(-1, &status, WNOHANG);
DXEC函数族
进程调用exec函数族执行某个程序
进程当前内容被指定的程序替换
实现让父子进程执行不同的程序
父进程创建子进程
子进程调用exec函数族
父进程不受影响
进程 – execl / execlp
#include <unistd.h> int execl(const char *path, const char *arg, …); int execlp(const char *file, const char *arg, …);
成功时执行指定的程序;失败时返回EOF
path 执行的程序名称,包含路径
arg… 传递给执行的程序的参数列表
file 执行的程序的名称,在PATH中查找
#include <unistd.h> #include <stdio.h> int main(){ if(execl("/bin/ls", "ls", "-a", "-l", "./", NULL) < 0){ perror("execl"); } printf("I ls current dircctory\n"); return 0; }
最后的一个参数一定是空!!!
execl之后的所有内容都会被替换掉,不会执行!!!!
进程 – execv / execvp
#include <unistd.h> int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]);
成功时执行指定的程序;失败时返回EOF
arg… 封装成指针数组的形式
与上面的程序类似,但是argv可以变化,更灵活一些,推荐使用。
system
#include <stdlib.h> int system(const char *command);
成功时返回命令command的返回值;失败时返回EOF
当前进程等待command执行结束后才继续执行
守护进程
守护进程(Daemon)是Linux三种进程类型之一
通常在系统启动时运行,系统关闭时结束
Linux系统中大量使用,很多服务程序以守护进程形式运行
特点:
始终在后台运行
独立于任何终端
周期性的执行某种任务或等待处理特定事件
Linux以会话(session)、进程组的方式管理进程
每个进程属于一个进程组
会话是一个或多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话。所有通过该终端运行的进 程都属于这个会话
终端关闭时,所有相关进程会被结束
守护进程创建
1.创建子进程,父进程退出
if (fork() > 0) { exit(0); }
子进程变成孤儿进程,被init进程收养
子进程在后台运行
2.子进程创建新会话
if (setsid() < 0) { exit(-1); }
子进程成为新的会话组长
子进程脱离原先的终端
3.更改当前工作目录
chdir(“/”); chdir(“/tmp”);
守护进程一直在后台运行,其工作目录不能被卸载
重新设定当前工作目录cwd
4.重设文件权限掩码
if (umask(0) < 0) { exit(-1); }
文件权限掩码设置为0
只影响当前进程
5.关闭打开的文件描述符
int i; for(i=0; i<getdtablesize(); i++) { close(i); }
关闭所有从父进程继承的打开文件
已脱离终端,stdin / stdout / stderr无法再使用
示例代码
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <time.h> int main(){ pid_t pid; //first step pid = fork(); if(pid < 0){ perror("fork"); return -1; }else if(pid > 0){ exit(0); } //second step pid = setsid(); if(pid == -1){ perror("setsod"); return -1; } //third step chdir("/"); umask(0); int i; for(i = 0;i < 2;++i){ close(i); } FILE *fp; time_t ctm; fp = fopen("1.log", "w"); while(1){ ctm = time(NULL); fputs(ctime(&ctm), fp); fflush(fp); sleep(1); } return 0; }
写在最后
今天开启并发编程,我尽量一天一更,大家和我一起变强呀!明天开始进入线程专题!最后三连即可提高学习效率!!!
另外我在更新的就是算法笔记的一些例题笔记,这个系列是用于提高我的算法能力,如果有兴趣对算法领域感兴趣找不到合适的入门文章也可以追更,如果我更新的太慢了请大家点赞收藏,一键三连才能更有更新的动力呀0.0