linux 进程的管理、子进程创建、进程资源的回收
来源:互联网 发布:自动归类的软件 编辑:程序博客网 时间:2024/06/06 03:27
今天介绍进程的进程的管理,子进程创建以及进程资源的回收
首先什么是进程?
答:进程是程序的实例。程序是静态的,是存放在硬盘上的,程序运行起来就形成了进程。程序从磁盘到内存里之后就形成了进程。
进程又分为:用户级进程和内核级进程
我们下面了解用户级进程:
操作系统为了和管理进程,会有一个控制块来记录进程用到了哪些资源。叫做PCB块。
每一个进程都有自己的一个ID叫做PID。
用以下命令可以查看当前的进程
pstree 查看进程树 (init的PID为1)
ps -aux 查看当前的进程表
ps -o pid,ppid,..... 查看当前bash下的进程的信息(信息自己添加如PID PPID)
下面介绍一个创建子进程的函数fork()
#include<unistd.h>
pid_t fork (void)
功能:创建一个子进程
参数:无
返回值:成功时,在子进程中返回0,在父进程中返回子进程的PID (在A进程里创建了B子进程,A就是B的父进程)。
失败时返回- 1 errno被设置
子进程会继承父进程的PCB里的所有资源(他们除了PID不一样其余在你使用fork()函数之后的一切东西都一样);
介绍函数exit()
#include <stdlib.h>
void exit(int status);
功能:使进程正常终止参数:指定退出的值。将status&0377 的数值传递给父进程
在进程终止之后,还有一部分资源滞留在系统中,我们需要回收进程所占用的资源
使用wait()函数可以回收进程的资源
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);
功能:阻塞等待子进程的终止,子进程终止的时候回收子进程的资源,立即返回
参数:
status:用来存储子进程状态码的地址,如果为NULL ,不希望保留子进程的退出状态码,可以使用宏来检测退出状态
WIFEXITED(status):如果子进程正常终止,返回真
WEXITSTATUS(status):在上个宏返回真的情况下才能被使用.获取子进程的退出状态码的低8位
WIFSIGNALED(status):如果子进程是被一个信号终止的返回真
WTERMSIG(status):返回终止子进程的信号的编号,在上个宏为真的情况下使用
返回值:成功返回种植的子进程的PID,失败返回-1
僵尸进程:子进程已经终止但是父进程没有回收他的资源,这时候子进程就是僵尸进程状态
孤儿进程;:父进程结束了,子进程还没结束。这时候子进程就叫做孤儿进程。并且他会过继给INIT 1号进程(INIT当他的父进程)
创建的子进程和父进程默认是同组的。
下面代码演示:
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<unistd.h> 4 #include<stdlib.h> 5 #include<sys/wait.h> 6 int main(){ 7 int a; 8 pid_t pid; 9 pid=fork(); 10 if(pid==-1){ 11 perror("fork"); 12 return -1; 13 } 14 if(pid==0){//子进程 15 getchar(); 16 exit(7); 17 }else{ 18 wait(&a); 19 printf("回收成功!\n"); 20 if(WIFEXITED(a))printf("son exit status=%d\n",WEXITSTATUS(a)); 21 if(WIFSIGNALED(a))printf("kill signal num=%d\n",WTERMSIG(a)); 22 } 23 return 0; 24 }
结果如下:
tarena@ubuntu:~/LIANXI/10.19$ gcc wait_a.ctarena@ubuntu:~/LIANXI/10.19$ ./a.out回收成功!son exit status=7在执行程序之后,由于在父进程中wait的存在,他会一直等子进程结束并回收其资源。当我们输入任意指令跳过子进程中的getchar时,子程序结束。
第21行代码:如果我们没有去跳过getchar 而是被一个信号中断了程序 如 kill -9 pid(子进程的pid,利用ps -aux 查看,或直接在程序中getpid)时,会打印终止我们程序的信号编号。
下面介绍在进程执行过程中,加载新的映像(可执行文件),来替换掉从父进程那里继承来的映像的函数:
函数: exec(3)系列函数
#include <unistd.h>extern char **environ; //全局变量 指向了环境变量列表的首地址 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 *const argv[]); int execvp( const char *file, char *const argv[]);功能:执行程序
参数:
共同点:都有exec
l:列表形式 const char *arg 和 char *const argv[] 的区别,有l的话需要将数组的每个成员都写在函数形式参数那里。
V:向量形式 只需要写数组的名字即可
都需要在函数的第二个参数后面加上NULL
p:如果有p就是const char *file (这里只需要填写要执行的可执行程序的名字,但是PATH环境变量里必须能找到这个可执行文件)没有就是const char *path 写的时候需要加上路径(比如./)
e:没有e就是子进程继承父进程的环境变量,有e就是给子进程传递新的环境变量
返回值:执行成功不返回,不成功返回-1
演示一个简单的,代码如下:
首先这个代码输出当前进程的环境变量:
1 #include<stdio.h> 2 extern char **environ; 3 int main(){ 4 int i=0; 5 for(i=0;environ[i]!=NULL;i++){ 6 printf("%s\n",environ[i]); 7 } 8 return 0; 9 }下面这个代码演示把上面的程序替换为创建的子进程的程序
1 #include<stdio.h> 2 #include <unistd.h> 3 #include <unistd.h> 4 int main(){ 5 pid_t pid=fork(); 6 char *const envp[]={"caption=beijing","wo=cool",NULL}; 7 if(pid==-1){ 8 perror("fork"); 9 return -1; 10 } 11 if(pid==0){ 12 execle("./a","a",NULL,envp); 13 }else{ 14 getchar(); 15 } 16 return 0; 17 }
运行结果如下:
tarena@ubuntu:~/LIANXI/10.19$ gcc execl.ctarena@ubuntu:~/LIANXI/10.19$ ./a.outcaption=beijingwo=cooltarena@ubuntu:~/LIANXI/10.19$
下面讲一下在当前bash下运行一个程序发生了什么?
首先什么是bash?
bash也是一个程序,是操作系统和用户交互的一个进程。
写在bash这个大程序里的小程序叫做内部程序
和bash 互相独立的程序叫做外部程序
所以bash也有自己的环境变量
环境变量又分为自定义变量和环境变量,自定义变量只是适用于当前进程,环境变量是子进程可以继承的环境变量。
当我们运行一个程序时,这个程序实在bash中运行的。其实是bash用fork函数创建了一个子进程,子进程复制了bash的映像,然后在子进程的映像中调用了exec系列的函数,将我们写的程序的可执行文件(映像)替换为子进程从父进程那里复制来的映像。然后执行我们写的程序的可执行文件。
fork之后bash下建立了一个子进程,开始这个子进程和bash是共用一个PCB的,当子进程发生改变时,子进程复制了父进程的PCB并调用了exec系列函数,将你要运行的程序的进程的PCB替换掉你从父进程那里复制来的PCB。然后执行你的程序。
以上为个人总结!如有不妥请指教!
- linux 进程的管理、子进程创建、进程资源的回收
- 回收子进程的资源
- Linux进程创建,子进程对父进程资源“写时拷贝”的证明
- Linux进程创建,子进程对父进程资源“写时拷贝”的证明
- Linux进程管理之进程的创建
- Linux进程管理之进程的创建
- linux 进程的创建 和退出回收
- Day28、进程的管理(创建、退出)、子进程
- 子进程的创建
- 子进程的创建
- 进程管理--回收僵尸态子进程
- Linux间的进程通信;以及子进程的创建
- Linux创建子进程的具体过程
- Linux父进程创建子进程的方法,监控子进程的结束
- linux进程内核资源回收
- linux 信号 回收子进程
- 【IO进程】Linux C中回收线程资源的方法
- 进程的管理之进程创建笔记
- 从源码理解LinkedMap和HashMap的区别
- Java Web
- 第五章 使用形态学滤波对图像进行边缘及角点检测
- JAVA作业
- 对python中对象的理解
- linux 进程的管理、子进程创建、进程资源的回收
- Android屏幕适配基础(1)
- python基本数据类型总结
- 2017中国开源年会(COSCon'17) 正式开启-逐浪字库倾力支持
- 解决阿里云ECS 8080端口无法访问的问题
- Day02
- 数据结构--线性表(数组表述)
- Docker集中化web界面管理平台-Shipyard部署记录
- EASYUI-前端分页