2011-03-02 27 views
1

繼承人我的代碼細目。C execv()函數是否終止子進程?

我有一個程序,分叉一個孩子(並在一個文件中註冊孩子的PID),然後做它自己的事情。孩子成爲程序員與argv端莊的任何程序。當孩子完成執行時,它發送一個信號(使用SIGUSR1)回到父進程,以便父進程知道從該文件中刪除孩子。父母應該停下來,通過更新其表格來確認已刪除的條目,並繼續保留它的位置。

pid = fork(); 
switch(pid){ 
case -1:{ 
    exit(1); 
} 

case 0 :{ 
    (*table[numP-1]).pid = getpid(); //Global that stores pids 
    add();        //saves table into a text file 
    freeT(table);     //Frees table 
    execv(argv[3], &argv[4]);   //Executes new program with argv 
    printf("finished execution\n"); 
    del(getpid());      //Erases pid from file 
    refreshReq();      //Sends SIGUSR1 to parent 
    return 0; 
} 
default:{ 
    ... //Does its own thing 
} 
} 

的問題是,在後execv成功啓動和完成(A printf語句之前返回0讓我知道),我沒有看到在switch語句中的命令的其餘部分正在執行。我想知道execv是否有一個^ C命令,它會在完成時殺死孩子,從而永遠不會完成剩下的命令。我查看了手冊頁,但沒有發現任何有用的主題。

謝謝!

+1

解決一個完全不同的觀點:可以編寫table [numP-1] - > pid而不是(* table [numP-1])。pid – 2011-03-02 19:26:02

回答

2

execv 用當前進程替換當前進程。爲了產生一個新的過程,你可以使用例如system()popen(),或fork()的組合和exec()

+0

ah ... kk。所以execv在完成之後終止孩子,並且孩子沒有責任終止自己(只要新程序正確結束)。 Hrm ..我想我需要重新編碼我的代碼:( – 2011-03-02 19:39:55

+0

也請注意整個'SIGUSR1'是一個錯誤,子進程在終止時自然向父節點發送'SIGCHLD',然後希望父節點'等待'這個系統避免了試圖自己做信號的醜陋的競爭條件。 – 2011-03-02 20:47:09

4

execv替換爲不同的一個當前正在執行的程序。一旦新程序完成,它不會恢復舊程序,因此它被記錄爲「成功,execv不返回」。

因此,當且僅當execv失敗時,您應該看到您的消息「已完成執行」。

0

你預計會發生什麼?這是execv所做的。請閱讀the documentation它說:

的EXEC()函數系列用一個新的進程映像替換當前的進程映像。

也許你system或東西后,問環境產生新的進程除了當前的一個。或者..是不是你已經通過fork獲得了什麼?很難看到你想在這裏完成什麼。

1

其他人已經解釋了什麼execv和類似的功能,以及爲什麼下一行代碼永遠不會執行。下一個合乎邏輯的問題是,父母應該如何檢測孩子是否完成了?

在父母在孩子運行時應該什麼都不做的簡單情況下,只需使用system而不是forkexec即可。

或者,如果父母會做點別的孩子退出之前,這些都是關鍵點:

  • 當孩子退出時,家長會得到SIGCHLDSIGCHLD的默認處理程序被忽略。如果您想捕獲該信號,請在致電fork之前安裝處理程序。
  • 孩子退出後,家長應撥打電話waitpid清理孩子,並瞭解退出狀態。
  • 家長也可以在阻止模式下撥打waitwaitpid等到孩子退出。
  • 家長也可以在非阻塞模式下致電waitpid以確定孩子是否已退出。