Linux中建立程式常用的三個命令詳解!

老男孩IT教育機構發表於2023-05-06

  在Linux系統中,建立程式的命令主要有三種,分別是:fork命令、vfork命令、clone命令,接下來老男孩教育小編透過這篇文章為大家詳細介紹一下這三個命令,一起來看看吧。

  fork命令

  fork建立一個程式時,子程式只是完全複製父程式的資源,複製出來的子程式有自己的task_struct結構和pid,但卻複製父程式其它所有的資源。例如,要是父程式開啟了五個檔案,那麼子程式也有五個開啟的檔案,而且這些檔案的當前讀寫指標也停在相同的地方。所以,這一步所做的是複製。這樣得到的子程式獨立於父程式,具有良好的併發性,但是二者之間的通訊需要透過專門的通訊機制,如pipe,共享記憶體等機制,另外透過fork建立子程式,需要將上面描述的每種資源都複製一個副本。這樣看來,fork是一個開銷十分大的系統呼叫,這些開銷並不是所有的情況下都是必須的,比如某程式fork出一個子程式後,其子程式僅僅是為了呼叫exec執行另一個可執行檔案,那麼在fork過程中對於虛存空間的複製將是一個多餘的過程。

  但由於現在Linux中是採取了copy-on-write技術,為了降低開銷,fork最初並不會真的產生兩個不同的複製,因為在那個時候,大量的資料其實完全是一樣的。寫時複製是在推遲真正的資料複製。若後來確實發生了寫入,那意味著parent和child的資料不一致了,於是產生複製動作,每個程式拿到屬於自己的那一份,這樣就可以降低系統呼叫的開銷。所以有了寫時複製後,vfork其實現意義就不大了。

  frok()呼叫執行一次返回兩個值,對於父程式,fork函式返回子程式的程式號,而對於子程式,fork函式則返回零,這就是一個函式返回兩次的本質。

  在fork之後,子程式和父程式都會繼續執行frok呼叫之後的指令。子程式是父程式的副本。它將獲得父程式的資料空間,堆和棧的副本,這些都是副本,父子程式並不共享這部分的記憶體。也就是說,子程式對父程式中的同名變數進行修改並不會影響其在父程式中的值。但是父子程式又共享一些東西,簡單來說就是程式的正文段。正文段存放著由cpu執行的機器指令,通常是read-only的。

  vfork

  vfork系統呼叫不同於fork,用vfork建立的子程式與父程式共享地址空間,也就是說子程式完全執行在父程式的地址空間上,如果這時子程式修改了某個變數,這將影響到父程式。

  因此,上面的例子如果改用vfork()的話,那麼兩次列印a,b的值是相同的,所在地址也是相同的。

  但此處有一點要注意的是用vfork()建立的子程式必須顯示呼叫exit()來結束,否則子程式將不能結束,而fork()則不存在這個情況。

  vfork也是在父程式中返回子程式的程式號,在子程式中返回0。

  用vfork建立子程式後,父程式會被阻塞直到子程式呼叫exec或exit。vfork的好處是在子程式被建立後往往僅僅是為了呼叫exec執行另一個程式,因為它就不會對父程式的地址空間有任何引用,所以對地址空間的複製是多餘的,因此透過vfork共享記憶體可以減少不必要的開銷。

  clone

  系統呼叫fork()和vfork()是無引數的,而clone()則帶有引數。fork()是全部複製,vfork()是共享記憶體,而clone()是則可以將父程式資源有選擇地複製給子程式,而沒有複製的資料結構則透過指標的複製讓子程式共享,具體要複製哪些資源給子程式,由引數列表中的clone_flags來決定。另外,clone()返回的是子程式的pid。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952527/viewspace-2950361/,如需轉載,請註明出處,否則將追究法律責任。

相關文章