對於fork概念的簡單理解

基本概念

衍生(fork)是Unix編程中最強大的概念之一。fork系統調允許運行中的進程以編程的形式創建新的進程。這個新進程和原始進程一模一樣。進行fork操作時,調用fork的進程被稱爲“父進程”,新創建的進程被稱爲“子進程”。子進程從父進程處繼承了其所佔用的內存中的所有內容,以及所有屬於父進程的已打開的文件描述符,兩個進程共享打開的文件、套接字等。

子進程繼承了父進程內存中的所有內容。藉助這種方式,一個進程可以將一個500MBde代碼庫(codebase)裝入內存,然後該進程衍生出兩個子進程,這些子進程實際上各自享有一份已載入內存代碼的副本。子進程可以隨意更改其內存內容的副本,而不會對父進程造成任何影響

因爲子進程是一個全新的進程,所以擁有自己唯一的pid。子進程的上層進程(parent)顯然就是其父進程,因此子進程的ppid就是調用fork的進程的pid。

代碼示例

if fork
    puts "enter if block"
else
    puts "enter the else block"
end

執行如上所示的Ruby腳本,將得到如下的輸出結果:

entered the if block
entered the else block

通過輸出的結果可發現if分支和else分支在腳本執行中均被調用了,似乎有悖常識。但是從進程的角度觀察其實不難理解。對於fork方法的調用實際上返回了兩次,這是因爲fork創造了一個新進程,所以在調用進程(父進程)中返回了一次,在新建進程中又返回了一次。在上述代碼中添加pid打印可以更加清晰地瞭解這一過程。

if fork
    puts "entered the if block from #{Process.pid}"
else
    puts "entered the else block from #{Process.pid}"
end

可觀察到輸出結果

entered the if block from 398
entered the else block from 399

從觀察結果中可知if語句塊中的代碼是由父進程執行的,而else語句塊中的代碼是由子進程進行的。這種執行順序與fork的返回值有關,在子進程中fork返回nil,因爲nil爲假,所以子進程執行了else語句塊中的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章