web-dev-qa-db-ja.com

子プロセスを終了する方法-_exit()vs. 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()を使用しますか?

42
helpermethod

必ず_Exit()を使用する必要があります。 exit()は、atexit()で追加した関数を呼び出し、tmpfile()で作成したファイルを削除します。親プロセスは実際に存在するときにこれらの処理を実行するものなので、_Exit()を呼び出す必要がありますが、これらはいずれも実行しません。

_Exit()が大文字のEであることに注意してください。_exit(2)は、おそらく直接呼び出したいものではありません。 exit(3)および_Exit(3)はこれを呼び出します。 _Exit(3)がない場合、はい、_exit()が望みのものです。

47

Fork()の子は常に_exit()を呼び出す必要があります。

代わりにexit()を呼び出すと、保留中のstdioバッファーが2回フラッシュされます。

15
Joshua

execvpは、成功した場合に子を終了するため、終了する必要はありません。

Execveが失敗すると、子でexit(EXIT_FAILURE);を使用します。

編集:私はいくつかの研究の後にそれを見つけました: http://www.unixguide.net/unix/programming/1.1.3.shtml

だから、C++を使用している場合は、フォークの子で_exit()を特別に使用する方が良いように見えます:p

3

それはあなたが望む振る舞いに依存します:man -s 3 exitおよびman _exitシステムの詳細について。一般的に、exitはatexit()で登録された関数を実行しますが、exitはこれらの関数を実行します(これらの関数はexitを呼び出さない方がよい-そうでない場合は再帰を取得します)。

一般に、必要に応じて_exitを呼び出す関数では、atexitで登録された関数を除き、_exitよりもexitの方が好きです。

1
jabbie

exit()はANSI-C関数であるため、オペレーティングシステムに依存しません。すべてのANSI-C標準関数を閉じます。 _exit()はオペレーティングシステムに依存する機能を閉じるためにexit()によって呼び出されます。これは、exit()がそれらについて認識していないためです。(exitはオペレーティングシステムに依存しません)

0
ImanKh