2011-08-23 104 views
6

我試圖用fork和execlp程序,其中父地址空間替換爲「ls」命令。叉和Execlp

#include<stdio.h> 
main() 
{ 
    int pid,j=10,fd; 
    pid=fork(); 
    if(pid==0) 
    { 
     printf("\nI am the child\n"); 
     execlp("/bin/ls","ls",NULL); 
     printf("\nStill I am the child\n"); 

    } 
    else if (pid > 0) 
    { 
     printf("\n I am the parent\n"); 
     wait(); 
    } 
} 

當我執行程序的孩子

printf("\nStill I am the child\n"); 

的最後一行不打印。爲什麼?

回答

16

exec家庭功能在成功時不會返回。

http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html

功能的高管家屬應帶一個新的進程映像替換當前的進程映像。新圖像應該由一個稱爲新過程映像文件的常規可執行文件構建。由於調用過程映像被新過程映像覆蓋,因此成功執行將不會返回。

如果其中一個exec函數返回到調用過程映像,則發生錯誤;返回值應爲-1,並應設置errno來指示錯誤。

4

exec函數不會僅執行您的命令。他們實際上會用您選擇的可執行文件替換進程的執行上下文(您的情況爲/bin/ls)。

換句話說,由於ls函數以終止其進程(「退出」或返回主函數或其它)結束,所以在執行ls時,您的子進程將被終止。

實際上,你可以用這個printf的調用來打印一些錯誤,例如:

if(pid==0) 
    { 
     printf("\nI am the child\n"); 
     execlp("/bin/ls","ls",NULL); 
     printf("\nError: Could not execute function %s\n", "/bin/ls"); 
     _exit(0); //make sure you kill your process, it won't disappear by itself. 
    } 
0

功能execlp()之後沒有得到按execlp 因此您的printf()語句的文件執行「我仍然是孩子「不會被執行......!

-3
  1. 您正在進程ID int類型,但實際上,存儲進程id,你應該當您使用exec類的函數調用整個進程的地址空間替代調用過程中使用pid_t
  2. 。所以,現在最後printf說法是不存在的新的過程,事實上,即使是進程的進程ID也不會改變
+0

幾個好點,但在新的過程中,pid肯定是不同的。另外,如果exec成功,exec只會替換進程,否則它將在exec調用之後繼續 – techdude

1

原因很簡單:EXEC()如果錯誤已經具備的功能只返回發生。對於相同的請參閱exec()函數的手冊頁。

什麼時候執行exec()函數調用到底正在發生:

EXECL()不創建一個新的進程 - 它修改 威斯和相關的內容 - 此外,執行上下文 也被修改。

  • 舊執行上下文不再使用 - 創建新的執行上下文。
    • 一個新的,新的上下文爲新加載的應用程序創建和 控制傳遞給scheduler-調度恢復同孩子 工藝與新獲得的執行上下文 - 使用此,跳轉 執行到入口新應用程序的一個點,在用戶空間中 - 新應用程序開始在相同的子進程中執行。
      • 系統堆棧被新的hw上下文覆蓋 在用戶空間中恢復新程序的main()。
    • 子進程中的舊應用程序的執行上下文和代碼/數據/堆/堆棧被完全銷燬 - 不再可用。
    • 當execve()或execl()無法在當前進程中加載​​ 新應用程序時,execve()或execl()將返回到當前進程的相同應用程序/代碼 --意思是唯一的時間 當完成execv()/ execl()/調用系列時出現 錯誤時,execv()/ execvl()或系列調用將返回。

注意:您必須對 錯誤/錯誤代碼驗證的exec()系列系統調用的API的返回值 - 基於誤差/錯誤代碼, 您可以終止當前進程或採取一些其他 操作。