2010-02-24 38 views
40

考慮以下代碼片段:如何退出子進程 - _exit()與出口

pid_t cpid = fork(); 

if (cpid == -1) { 
    perror("fork"); 
    exit(EXIT_FAILURE); 
} 

if (cpid == 0) { // in child 
    execvp(argv[1], argv + 1); 
    perror("execvp"); 
    _exit(EXIT_FAILURE); 
} 

// in parent 

如果execvp收益應如何我退出的子進程?我應該使用exit()還是_exit()?

回答

46

您應該一定使用_Exit()exit()調用您添加的功能atexit()並刪除使用tmpfile()創建的文件。由於父進程確實是在存在的時候需要完成這些工作的進程,因此應該調用_Exit(),這些都不起作用。

通知_Exit()大寫E. _exit(2)可能不是您想要直接調用的。 exit(3)_Exit(3)會爲你打電話。如果你沒有_Exit(3),那麼是的,_exit()是你想要的。

+3

+1您希望失敗的子進程安靜地退出,就好像它從未創建過一樣。 – 2010-02-24 21:49:58

+2

既然舊C標準允許鏈接器解決大小寫不敏感_Exit()不能是標準庫函數,因爲它會與舊的_exit()衝突。抱歉。 – Joshua 2010-02-24 21:50:15

+7

恰恰相反。 _Exit(3)是一個標準C庫(ISO C99)。 _exit(2)是POSIX.1系統調用,不是C標準。 – 2010-02-25 01:06:48

3

如果成功,execvp將退出子項,所以您不必退出。

關於execve失敗,我只是在孩子中使用exit(EXIT_FAILURE);

編輯:我發現了一些研究之後:http://www.unixguide.net/unix/programming/1.1.3.shtml

所以它看起來是更好的叉孩子使用_exit()特別是當你在C++:對 感謝您的問題,我學到了一些東西:d

+0

而當你使用_exit()? – helpermethod 2010-02-24 21:30:33

1

這取決於你想要的行爲:man -s 3 exitman _exit關於你係統的更多細節。一般來說,我相信_exit不會運行使用atexit()註冊的函數,而exit(這些函數最好不要調用exit - 否則您會得到遞歸)。

一般來說,我寧願退出_exit除了在用atexit註冊的函數,在那些我會叫_exit,如果需要的話。

15

fork()的孩子應該總是調用_exit()。

調用exit()代替是一種很好的方法,可以使掛起的stdio緩衝區刷新兩次。

+1

除非出現錯誤,否則exec不會返回,您在其中調用_exit。 – Joshua 2014-02-14 04:01:00

0

exit()是ANSI-C函數,因此它是獨立於操作系統的。它關閉了所有的ANSI-C標準功能。 _exit()被稱爲exit()關閉操作系統相關的功能,因爲exit()沒有關於他們的想法。(exit是獨立於操作系統)

+0

「_exit()是Linux內核函數」不正確,請參閱http://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html – 2016-10-06 11:37:33

+0

你說得對,但我的其餘評論是真實的。請參閱:David Curry的「Unix系統編程」,第291頁。 – ImanKh 2016-10-06 17:39:07