Linux进程 小结

基本定义

Process is a program in execution. 执行中的程序
  -It associates with all the files opened by that process. 文件
  -It attaches to all the memory that is allocated for it. 内存
  -It contains every accounting information, 统计信息 e.g. running time, current memory usage, who owns the process,etc.
 

创建进程

fork() : 复制生成了一个子进程,子进程从调用fork的地方开始执行

复制了什么?

复制了 User space memory 中的所有内容,包括本地变量,全局变量,动态分配变量,代码和常量。

Kernel Space 中 只复制了文件数组,其他的比如PID,Running time,Children,Parent都不同。

fork() 方法的返回值不同,父进程返回子进程的PID,子进程返回0。

结果:

由于文件数组相同(包括标准输出,输入和错误输出),子进程与父进程打印的内容出现在同一个窗口。

父进程和子进程的执行顺序是不确定的,由系统的scheduler决定。

 

子进程的使用

exec*() 有6个成员函数

22111205_q2To.png

在User space上,所有本地变量和动态分配变量(栈和堆)被清空,代码变成新的代码,常量相应地改变,全局变量根据新代码进行设置。

在kernel space上,重置了 register ,比如 program counter。其他基本保留着,比如PID,Parent等。(文件数组呢?标准输出,输入,错误输出还是不变的,其他的应该也重置了(待确定))

结果:

一旦子进程执行了exec*(),不会再返回之前的代码(不同于普通的函数调用)。

 

子进程与父进程的协调

exit() :由子进程调用,表明运行结束。

在User space中,所有东西都会被清除。

在Kernel space中,分配的内存会被回收,所有相关文件都会关闭,但是保留PID还有退出状态(exit status),成为了zombie。

最后,kernel会发出SIGCHLD信号给父进程。

 

wait() : 由父进程调用,用于等待子进程运行结束 termination

kernel会为父进程注册一个signal handling routine用于将来处理SIGCHLD信号

如果父进程的子进程还未执行结束,父进程就会被挂起,直到收到了SIGCHLD,signal handling routine被触发,将子进程的zombie处理干净(彻底从kernel space中清除),然后wait()会返回子进程的PID。

如果父进程没有fork过任何子进程或者子进程早已运行结束,上述的清理流程会立刻执行。

 

waitpid() : 与wait()的区别在于,它能够指定某一个子进程的PID,并且可以侦测子进程的其他状态改变(而不仅仅是termination)

 

调用wait()的意义

系统资源利用:Linux中PID是有限的,zombie进程会占据一个PID,如果zombie一直产生但没有被处理,那么PID将可能被耗尽,系统无法创建新进程。

经典的可以造成死机的代码片段

int main(){
  while(fork());
  return 0;
}

 

关于re-parent:

Linux中, init进程会成为所有的“孤儿”进程的后妈。这个过程叫做re-parenting.

注意: 新的Linux kernels 可能不再选择init进程而是 祖父进程, user-level init进程等。

 

问题:zombie存在的意义?

答:确保无论父进程调用wait()的时间是在子进程结束之前还是之后,父进程都能够获取子进程结束的一些信息(比如 是否非正常退出?)。 参考:http://stackoverflow.com/questions/16416793/why-is-a-zombie-process-necessary 

 

问题: 如果zombie进程的父进程忘记了wait,怎么清除zombie ? 

答: 杀死那个父进程,那么这个父进程的所有子进程都会reparent,通常是init进程会成为他们的新父进程,接着init进程会wait它们,最后成功清除zombie。 参考: http://stackoverflow.com/questions/16944886/how-to-kill-zombie-process

 

问题:哪个process是系统的第一个进程?

答: init进程。 

 

进程的生命周期

165143_ZNNA_2242731.png

eady:指一个进程处于可以run但是还没run的状态,也可以理解为 runnable状态。

什么时候进程会处于ready状态? 1. 刚刚被fork出来 2. CPU context-switch到另外的进程 3. 刚从Blocked/Waiting状态返回

Running:进程获得了CPU,并且正在运行。

Blocked/Waiting : 显式地或者隐式地等待某些事情发生, 比如 在读取文件,父进程调用wait() 等。

有interruptable和un-interruptable两种类型,顾名思义,后一种类型的blocked状态是无法打断的,通常是一些特殊的API在驱动程序driver被滥用,导致电脑的卡顿现象。

问题:有没有什么办法打断un-interruptable blocked状态?

答:没有!除非关机,重启~

 

后台进程与前台进程

当在shell执行一个程序时,新建的进程默认是前台进程。前台进程继承了父进程(shell进程)的所有文件也包括了标准输入输出和错误输出,因此用户可以通过标准输入输出和新进程进行交互。

但是,当新进程收到了SIGTSTP信号被挂起时,或者运行程序时使用&指令,进程都会变成后台进程,此时,标准输入就不再可用。

注意:当进程因为SIGTSTP信号被挂起,而后又收到SIGCONT继续执行时,它仍然是作为后台进程在运行。(更多关于信号的内容,参见 https://my.oschina.net/Bruce370/blog/885260

在shell调用fg指令,可以将后台进程带到前台。

 

转载于:https://my.oschina.net/Bruce370/blog/884739

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值