wait函数的作用
前言
在編寫C程序的時候, 通過fork函數來創建新的進程, wait函數來等待子進程結束.
那么就有一個問題了, 什么情況下父進程需要等待子進程結束后繼續執行呢? 如果需要等待子進程結束, 那直接將操作放到父進程執行不就醒了么? 反正等著也是等著.
當然, 還有有一種情況, 任務A 和任務 B 是后續操作的前提條件, 并且兩個任務可以并行進行, 此時確實可以父進程執行一個, 子進程執行一個, 然后父進程等待子進程完成后繼續操作. 但是, 我還是覺得這個解釋并不是那么完美. 這完全可以通過進程通信實現啊.
因此, 我覺得wait函數的出現一定是有著其他用途的.
這個問題在我重翻操作系統之后有了答案.
為什么
眾所周知, 進程在操作系統中運行的過程中是存在PCB(進程管理塊)模塊的. 它是進程的唯一標識符, 一般保存著PID、運行狀態、資源信息等等.
進程在調用exit函數退出時, 會對占有的資源進行回收. 注意, 在exit函數回收資源的這段時間, 該進程仍然在運行中. 因此, 有一個資源是進程無法自己進行回收的, 就是PCB. 進程要運行就需要PCB, 而PCB回收的前提就是進程已經不在運行了. 也就是說, 進程自己是無法回收自己的.
那么PCB就無法回收了么? 當然不是, 該wait函數出場了. 既然進程自己無法回收自己, 那么就由父進程負責回收咯. 因此, 這么一個等待子進程結束的函數也就有了用武之地.
順帶一提, 在子進程exit執行結束, PCB資源回收之前的這段時間, 子進程的狀態被稱為僵尸態, 很形象了.
mac中的進程:
debian中的進程:
可以看到, PID為0的進程是所有進程的父進程. 在mac中, 所有進程都由/sbin/launchd進行創建, debian中則為kthreadd. 他們的作用就是對進程進行管理和調度. 父進程通過fork創建子進程, 之后子進程再通過exec更換為要執行的進程.
而這個PID為0的進程, 也是系統在運行過程中唯一一個不是通過fork創建的進程.
但是, 還有一個問題, 那就是如果父進程沒有等子進程結束呢? 子進程結束的時候, 發現其父進程早就結束了, 那它的PCB 無法回收了么? 當然不會, 這個PID為0的祖宗進程, 或者稱為root進程會定期掃描所有的僵尸進程, 并且代替其父進程對其進行回收.
了解了之后恍然大悟, そうですね!!!
原文地址: https://hujingnb.com/archives/733
總結
- 上一篇: mysql允许两个用户远程连接,配置My
- 下一篇: egret 变量_egret性能优化总结