1、html
下面的代碼是對fork的測試vim
運行結果爲:ide
能夠看出,全部進程的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
多搜幾回,直到搜索到定義。
搜到的定義以下:
3、
先看下面這段代碼:
當註釋的那段 sleep(5)存在時,
父進程要比子進程結束地晚,這時,輸出的結果爲:
這符合咱們的預期
然而,若是想我圖片中那樣註釋掉 sleep(5) 這一行代碼,
父進程會先於子進程結束。
對於子進程來講,它正在執行,忽然它的父進程結束了,
這時候,該子進程就叫作「孤兒進程」,
它的父進程變爲 init(1號進程)
4、
(這部份內容參考:http://www.kuqin.com/shuoit/20141122/343361.html)
將上面的代碼改一下,把fork更改成vfork
修改後的代碼以下圖:
實際上,vfork()建立的子進程 跟父進程除了共享代碼之外,還共享數據
也就是說,fork() 是 寫時拷貝,而vfork()是共享
這時候,一旦子進程開始執行的時候,父進程將被阻塞,直到子進程 正常結束 異常結束或exec,父進程才繼續執行。
所以,vfork()能夠保證子進程始終要先於父進程結束。
在上圖的代碼中,當子進程的那部分代碼用 exec的方式結束時,程序可以正常執行,分別輸出 子進程和父進程的pid
但若是用return 0 的方式結束,執行程序,會發現程序進入了以下圖的相似死循環的狀態,掛掉:
這是因爲:
對於子進程,它執行exit(),操做系統會結束該進程,並讓父進程繼續工做;
而子進程一旦執行return 0,因爲其數據與父進程徹底共享,return 0 的做用也發生在父進程上,這時父進程的棧幀會被改變,這時發生的事情是未知的,在某些內核版本中,程序會報「棧錯誤」,而另外一些內核版本中,程序會再次進入main函數開始執行,就形成了死循環。