fork函數(shù)通過系統(tǒng)調(diào)用創(chuàng)建一個與原來進程幾乎完全相同的進程。一個進程調(diào)用fork()函數(shù)后,系統(tǒng)先給新的進程分配資源,例如存儲數(shù)據(jù)和代碼的空間。然后把原來的進程的所有值都復(fù)制到新的新進程中。相當于克隆了一個自己。
也就是說,原來的進程和fork出來的子進程的進程空間是完全一樣的,包括 代碼段,數(shù)據(jù)段,bss段,堆區(qū),共享內(nèi)存,棧區(qū)。如下圖所示:

下面是幾個關(guān)于子進程復(fù)制父進程的內(nèi)存空間的一些細節(jié):
寫時拷貝
再進行內(nèi)存空間的復(fù)制的時候,這里使用了copy-and-write(寫時拷貝)的方式。簡單的說,就是資源的復(fù)制是在需要寫入的時候才會進行,在此之前,只有以只讀方式共享。(寫時拷貝是一種可以推遲甚至避免拷貝數(shù)據(jù)的技術(shù)。內(nèi)核此時并不復(fù)制整個進程的地址空間,而是讓父子進程共享同一個地址空間。只用在需要寫入的時候才會復(fù)制地址空間,從而使各個進行擁有各自的地址空間。)fork 之后 關(guān)于文件的問題
在Linux系統(tǒng)中,常常存在許多對文件的操作,fork()的執(zhí)行將會對文件操作帶來一些小麻煩。由于子進程會將父進程的大多數(shù)數(shù)據(jù)拷貝一份,這樣在文件操作中就意味著子進程會獲得父進程所有文件描述符的副本。(也就是文件句柄包含著當前文件的偏移量以及文件狀態(tài)標志 都是完全相同的)

-
vfork 和 fork的區(qū)別
vfork與fork相似,但是也有區(qū)別,具體區(qū)別歸結(jié)為以下3點:fork() 子進程拷貝父進程的數(shù)據(jù)段,代碼段. vfork() 完全和父進程共享內(nèi)存,包括堆、BSS、初始化非0數(shù)據(jù)區(qū)等區(qū)域。
fork() 父子進程的執(zhí)行次序不確定. vfork():保證子進程先運行。
為什么要使用 vfork?
因為以前的fork當它創(chuàng)建一個子進程時,將會創(chuàng)建一個新的地址空間,并且拷貝父進程的資源,而往往在子進程中會執(zhí)行exec調(diào)用,這樣,前面的拷貝工作就是白費力氣了,這種情況下,聰明的人就想出了vfork
-
fork函數(shù)在執(zhí)行復(fù)制內(nèi)存空間的時候,之前會做什么?
https://blog.csdn.net/wenqian1991/article/details/46367213linux 進程:
https://blog.csdn.net/wenqian1991/article/details/38798289
https://blog.csdn.net/wenqian1991/article/details/23865457
-
什么是僵尸進程?
進程退出后,系統(tǒng)會把該進程的狀態(tài)變成Zombie,然后給上一定的時間等著父進程來收集其退出信息,因為可能父進程正忙于別的事情來不及收集,所以,使用Zombie狀態(tài)表示進程退出了,正在等待父進程收集信息中。# 查看僵尸進程 ps -aux | grep ‘Z’
-
如何防止僵尸進程的出現(xiàn)?
子進程結(jié)束的時候,會產(chǎn)生一個sigchld信號??梢栽诟高M程里面加入對這個信號的處理函數(shù)。在處理信號的函數(shù)里面調(diào)用wait 或 wait_pid 函數(shù),回收子進程。這里有一個問題,就是如果有100個子進程需要收回,每一個子進程結(jié)束的時候,都會發(fā)送sigchild信號。很有可能是同時發(fā)送信號。但是信號機制,是不支持排隊的。所以,在信號處理的函數(shù)里面要調(diào)用wait_pid + WNOHANG參數(shù)。
WNOHANG參數(shù) 表示即使沒有子進程退出,它也會立即返回,不會像wait那樣永遠等下去。 這樣wait_pid就不會阻塞如果感興趣的話,可以看這個 :
https://www.cnblogs.com/wuchanming/p/4020463.html -
關(guān)于進程打開文件 以及 文件系統(tǒng)的補充
一個進程去打開一個文件之后,會返回一個文件描述符。這個描述符對應(yīng)了一個文件打開表。文件打開表對應(yīng)著inode的結(jié)點。inode對應(yīng)block。
