linux學習筆記 (fork && FILE && PC)

1、html

下面的代碼是對fork的測試vim

wKiom1dnt9_zgSzPAACUlAwxU_o291.png

運行結果爲:ide

wKiom1dnuBfxhJ9dAAC6tIORnao743.png

能夠看出,全部進程的pid 爲 10604 ~ 10611  (共 8 個   2 ^ 3)函數

 

修改循環條件,讓循環執行5次,測試

全部進程的pid 爲 : 10637 ~ 10668 (共 32 個  2 ^ 5)spa

 

能夠看出,循環執行n次,進程的數目爲: 2 ^ n 個操作系統

 而printf的次數則要加上先前的進程數目,3d

 

這能夠類比於滿二叉樹,htm

進程的數目至關於當前層的結點數目之和,而printf的次數至關於當前結點及以前的全部節點的數目之和blog

2、

FILE結構體:

首先定位:

cd /usr/include

搜索:

gerp 'FILE' stdio.h

 

搜索出了一大堆,但其中有一行代碼:

 typedef struct _IO_FILE FILE;

因此接下來搜索 _IO_FILE:

  grep '_IO_FILE' *.h

搜索出了幾行,其中有一行:

   libio.h:struct _IO_FILE

這說明咱們要找的_IO_FILE 是在 libio.h

因此接下來打開libio.h

 vim libio.h

而後,在底欄模式下搜_IO_FILE

:/_IO_FILE

多搜幾回,直到搜索到定義。

搜到的定義以下:

wKiom1dnvmWxSoAHAAHiGXqqSrw156.png

 

3、

先看下面這段代碼:

wKiom1dnqwPjasHZAACVnFtvuH0609.png

當註釋的那段 sleep(5)存在時,

父進程要比子進程結束地晚,這時,輸出的結果爲:

wKiom1dnqzzDdbifAAAT85mZEmY773.png

這符合咱們的預期

 

然而,若是想我圖片中那樣註釋掉 sleep(5) 這一行代碼,

父進程會先於子進程結束。

 

對於子進程來講,它正在執行,忽然它的父進程結束了,

這時候,該子進程就叫作「孤兒進程」,

它的父進程變爲 init(1號進程)

 

 

4、

(這部份內容參考:http://www.kuqin.com/shuoit/20141122/343361.html

將上面的代碼改一下,把fork更改成vfork

修改後的代碼以下圖:

wKiom1dn_VHRsmEKAAC1My5S2bE363.png

實際上,vfork()建立的子進程 跟父進程除了共享代碼之外,還共享數據

也就是說,fork() 是 寫時拷貝,而vfork()是共享

這時候,一旦子進程開始執行的時候,父進程將被阻塞,直到子進程 正常結束 異常結束或exec,父進程才繼續執行。

所以,vfork()能夠保證子進程始終要先於父進程結束。

 

在上圖的代碼中,當子進程的那部分代碼用 exec的方式結束時,程序可以正常執行,分別輸出 子進程和父進程的pid

但若是用return 0 的方式結束,執行程序,會發現程序進入了以下圖的相似死循環的狀態,掛掉:

wKiom1dn_0vjHZmZAABqmPwbrsY418.png

這是因爲:    

    對於子進程,它執行exit(),操做系統會結束該進程,並讓父進程繼續工做;

 

    而子進程一旦執行return 0,因爲其數據與父進程徹底共享,return 0 的做用也發生在父進程上,這時父進程的棧幀會被改變,這時發生的事情是未知的,在某些內核版本中,程序會報「棧錯誤」,而另外一些內核版本中,程序會再次進入main函數開始執行,就形成了死循環。

相關文章
相關標籤/搜索