linux中的进程与线程,linux 进程与线程

Linux的每个进程(除了init进程以外)都依赖于一个父进程, 内核启动init作为第一个进程.

创建进程的方式有两种, 一种是fork,一种是exec

fork会生成一个父进程的副本,父进程和子进程只有PID不同,不过linux采用了一种copy on write 写时复制 的策略来使fork更加高效, 内存复制操作会被延迟到父进程或子进程向内存写入数据之前, 如果不需要写入, 父进程和子进程将一直使用同一内存页

exec将一个新程序加载到当前进程的内存中并执行, 旧进程的内存页将被替换成新数据

线程在linux系统中实际上是一种轻量级进程, linux用clone方法创建线程,  工作方式类似于fork, 但会采用更精确的检查机制

确实哪些资源与父进程共享,哪些是线程自己创建的

如果你使用过docker或者了解过docker的僵尸进程问题, 那么对以上的fork机制可能会有一个更清楚的认识

de04cb225254501c831947ee5f4b9d4b.png

这里你可以尝试使用bash来创建新线程, 这里假设init创建了3个bash进程,然后使用bash3再创建一个bash4, 那么父进程与子进程的结构就会跟上面一样

任何进程在运行结束以后并不会立即被销毁,而是要把自己mark成"活动已经停止"的状态,此时进程的pid还存在于系统的进程表中

子进程会持有一个父进程的pid , 而父进程也必需明确等待子进程运行结束之后对其进行回收,以便处理它的退出状态(通过waitpid())函数

只有在父进程对子进程处理结束后,子进程的pid才会被完全释放

这里如果父进程先于子进程结束(正常的运行结束,或者意外结束,或者被人为kill), 子进程都会变为一种"孤儿"状态, 孤儿进程的父进程会被直接指向到init进程

init进程的一个重要工作就是接收孤儿并对其进行收割, 不过docker的特殊之处在于, 每个docker容器的init进程并不是一个真正的init进程,实际上是用户指定的(例如普通的bash进程),它并不能接收和收割孤儿进程, 这些失去了父进程的子进程在运行结束之后,就会变成死亡的僵尸进程

9d5996e8c53527065c84075ea841c0fa.png

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值