linux 下的多線程編程(fork && exec系列)

來源:互聯網
上載者:User
fork

#include<unistd.h>
#include<sys/types.h>

函數定義:   pid_t fork(void);
  
(pid_t 是一個宏定義,其實質是int被定義在#include<sys/types.h>中)
 

 傳回值:若成功調用一次則返回兩個值,子進程返回0,父進程返回子進程ID;否則,出錯返回-1  

 函數說明:  
       一個現有進程可以調用fork函數建立一個新進程。由fork建立的新進程被稱為子進程(childprocess)。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。 
   子進程是父進程的副本,它將獲得父進程資料空間、堆、棧等資源的副本。注意,子進程持有的是上述儲存空間的“副本”,這意味著父子進程間不共用這些儲存空間,它們之間共用的儲存空間只有程式碼片段。


fork之後是父進程先執行還是子進程先執行,這是取決於cpu調用演算法的,就是說他們誰先執行都有可能。

===============================================================================================================

exec系列

說是exec系統調用,實際上在Linux中,並不存在一個exec()的函數形式,exec指的是一組函數,一共有6個,分別是:

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);


其中只有execve是真正意義上的系統調用,其它都是在此基礎上經過封裝的庫函數。

exec函數族的作用是根據指定的檔案名稱找到可執行檔,並用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行檔。這裡的可執行檔既可以是二進位檔案,也可以是任何Linux下可執行檔指令檔。

與 一般情況不同,exec函數族的函數執行成功後不會返回,因為調用進程的實體,包括程式碼片段,資料區段和堆棧等都已經被新的內容取代,只留下進程ID等一些表 面上的資訊仍保持原樣,頗有些神似"三十六計"中的"金蟬脫殼"。看上去還是舊的軀殼,卻已經注入了新的靈魂。只有調用失敗了,它們才會返回一個-1,從 原程式的調用點接著往下執行。

現在我們應該明白了,Linux下是如何執行新程式的,每當有進程認為自己不能為系統 和擁護做出任何貢獻了,他就可以發揮最後一點餘熱,調用任何一個exec,讓自己以新的面貌重生;或者,更普遍的情況是,如果一個進程想執行另一個程式, 它就可以fork出一個新進程,然後調用任何一個exec,這樣看起來就好像通過執行應用程式而產生了一個新進程一樣。

事 實上第二種情況被應用得如此普遍,以至於Linux專門為其作了最佳化,我們已經知道,fork會將調用進程的所有內容原封不動的拷貝到新產生的子進程中 去,這些拷貝的動作很消耗時間,而如果fork完之後我們馬上就調用exec,這些辛辛苦苦拷貝來的東西又會被立刻抹掉,這看起來非常不划算,於是人們設 計了一種"寫時拷貝(copy-on-write)"技術,使得fork結束後並不立刻複製父進程的內容,而是到了真正實用的時候才複製,這樣如果下一條
語句是exec,它就不會白白作無用功了,也就提高了效率。

此段來自: http://hi.baidu.com/%CF%E6%CB%AE%C0%CB%D7%D3/blog/item/946bb8c8a84e82027e3e6f1a.html

====================下面是看到的很形象的一個比喻==========來自:點我查看原文^_^============================

出自:http://blog.csdn.net/kaiwii/article/details/7254135

對於進程的一生可以用一些形象的比喻作一個小小的總結:隨著一句fork,一個新進程呱呱落地,但它這時只是老進程的一個複製。然後隨著exec,新進程脫胎換骨,離家獨立,開始了為人民服務的職業生涯。人有生老病死,進程也一樣,它可以是自然死亡,即運行到main函數的最後一個”}”,從容地離我們而去;也可以是自殺,自殺有2種方式,一種是調用 exit函數,一種是在main函數內使用return,無論哪一種方式,它都可以留下遺書,放在傳回值裡保留下來;它還甚至能可被謀殺,被其它進程通過另外一些方式結束他的生命。進程死掉以後,會留下一具殭屍,wait和waitpid充當了殮屍工,把殭屍推去火化,使其最終歸於無形。在linux中wait系統調用一文中介紹了其中的一個殮屍工wait, 下面介紹另一個waitpid,這個貌似複雜些。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.