linux進程編程:子進程創建及執行函數簡介


linux進程編程:子進程創建及執行函數簡介

子進程創建及執行函數有三個:

(1)fork();
(2)exec();
(3)system();
    下面分別做詳細介紹。
(1)fork()
    函數定義:
    pid_t fork();
    函數說明:
    linux下進程在內存中由三部分數據組成:代碼段、數據段、堆棧段。在一個進程中,調用fork函數,可以創建、啟動一個新進程。新進程與父進程共享代碼段,復制父進程的數據段和堆棧段。創建成功后,fork()會向兩個進程都有返回值。向父進程的返回值為子進程的進行號,向子進程的返回值為0。由於兩個進程共享代碼段,我們就利用兩個返回值的不同,通過if...else...區分兩進程在子進程啟動后的運行情況。
    返回值:
    創建成功后,fork()會向兩個進程都有返回值。向父進程的返回值為子進程的進行號,向子進程的返回值為0。函數調用失敗返回值為-1。錯誤原因存在於errno中。

(2)exec()函數族
    exec函數族共6個函數,函數原型:
    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 arg[]);
    int execvp(const char *file, char *const arg[]);
    int execve(const char *path, char *const arg[], char *const envp[]);
    函數族說明:
    exec()函數族通過指定路徑或文件名的方式找到並執行一個可執行文件。該可執行文件可以使二進制文件或linux系統下可執行的shell腳本文件,一旦執行即替代原進程代碼,廢除原進程數據段和堆棧段,但仍然沿用原進程的進程號。換句話說,原進程運行的程序已經換成了新的程序,但對系統而言還是同一個進程。如果我們的程序向啟動另一個程序的執行,還想原進程繼續運行,可以將fork和exec結合使用,先創建新進程,然后再新進程中使用exec調用需要啟動的程序。
    函數返回值:
    exec()函數族的函數執行成功后沒有返回值,調用失敗時才會返回-1,原程序由調用點繼續往下執行。
(3)system()
    函數定義:
    int system(const char *file);
    函數說明:
    system()相當於fork與execl的組合。首先由fork()函數建立了一個子進程,然后由execl()函數根據參數file給定的文件名找到並執行可執行文件。
    system()與exec函數族都可執行進程外的命令,區別是system()函數在原程序上創建一個新的進程,再在新進程中執行可執行文件;而exec函數族是在新開辟的進程中植入新代碼替代原程序代碼。
    函數返回值:
    函數調用成功返回0;調用失敗返回-1。若返回值的8~15位為127,則system()中的execl函數執行失敗。

以上轉至:linux進程編程:子進程創建及執行函數簡介

 

最后補充一下,如果用fork復制進程,那么在復制進程后調用的程序/應用內部一定要記得exit(0);做退出處理,不然會出現僵屍進程。

而且你會發現哪怕你在被調用的程序/應用A里面有做exit處理,下次繼續fork()得到的gid會依次遞增,不會復用上一個pid,為什么呢?

別着急,這是緩存機制,進程一旦退出,進程號可以重用的,但是為了避免誤認為是之前退出的進程,會有一定的延遲,不用擔心進程ID被你消耗完。

所以,放心,會重復利用的。一直加,加到最大,在重小的開始,又來一輪。

 

也可以參考下這篇文章:Linux多線程概述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM