父子進程那些事兒


  前一章文章我們簡單的說了一下父子進程以及fork函數,那么fork函數創建的新進程與原進程有什么聯系呢?如果其中一方結束了會怎么樣?他們真的形同父子嗎?他們的數據是否共享?以及一些其他的進程問題,這篇文章我們會講到。

一、父子進程

  通過fork函數創建的新進程是原進程的子進程,而調用fork函數的進程是fork函數創建出來的新進程的父進程。也就是說,通過fork函數創建的新進程與原進程是父子關系,fork就相當於一個憑證,有fork,就有父子關系。

  我們可以通過兩個函數來做實驗:

  getpid()  用於獲取調用getpid這個函數的進程的pid;

  getppid()  用於獲取調用getppid這個函數的進程的父進程的pid。

  以上這段代碼,我在父進程執行的代碼段,加一個sleep(1),這是因為,整個程序運行的時間太短,當子進程運行getppid時,父進程可能已經結束從而導致一些意料之外的結果,好在有sleep()函數幫我們完成了測試:

  可以看到,父進程在子進程結束之后再結束,使得子進程獲取了其父進程的pid,哦耶。

 


 

  既然剛剛說到,父進程結束了,而子進程並未結束,會有意料之外的事,這時會發生什么呢?

  來看:

  此時我讓子進程進入死循環,並且放入后台運行,從而使得我們可以一直獲取他們的pid,讓父進程直接結束。

  得到如下結果:

 

  可以看到,新進程的父進程pid變成了1,那pid為1的進程又是何方神聖呢?

  我們通過ps -A命令來查看:

  現在我們知道了,當父進程結束了,兒子進程未結束時,子進程就變成了所謂的孤兒進程該就交由init進程管理,init進程是一個守護進程,因為init這個進程管理了很多孤兒進程,所以也稱之為進程的孤兒院

 

 

二、數據共享

  我們現在通過一段代碼研究一下父子進程的是否存在數據共享。

  我們現在簡單把數據分成三種:堆區數據、棧區數據、全局數據。所以我現在有三個變量,同時,我讓子進程改變這三個變量的值。讓父進程沉睡兩秒鍾以確保子進程運行結束。

  結果如下:

  可以看到,其值發生了改變,這也說明,附子進程的堆區數據、棧區數據、全局數據是不共享的。

  


 

  那子進程能和父進程共享文件嗎?我們看看以下代碼:

  我先open一個我創建好的在同一目錄下的a.txt文件,a.txt文件中我寫了“Hello World!”

  讓父子進程一起一個字節一個字節的讀文件里字符,每讀一次sleep一秒鍾。

  結果如下:

  這是什么呢,這就是說,並不是一個進程操作一個文件時,另一個進程就不能操作,而且,父子進程可以同時操作同一個文件。

  也就是,在父子進程中,文件描述符以及文件偏移量,都是共享的!


   為什么文件就能共享了呢,在linux源碼里,每個進程都有一個PCB(進程控制塊)結構體,每個PCB里,存了一個結構體指針指向一個我們理解為文件描述符的結構體struct file,而這個結構體里,才存了文件的id,從什么地方開始寫,模式等等。值得注意的事,這個結構體里有一個指針才是指向真正的文件的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM