linuxシステムプログラミングのプロセス(四):プロセスはexitを終了し、exit区別すなわちatexit関数
作者:mickole出典:http://www.cnblogs.com/mickole/
一、プロセス終了には5つの方法があります.
正常終了:
main関数からを返す
呼び出しexit 呼び出し_exit
異常終了:
呼び出しabort 信号によって終了する二、exitと_exitの違い:
についてexit():
#include
void _exit(int status);
#include
void _Exit(int status);
DESCRIPTION The function _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process’s par- ent is sent a SIGCHLD signal.
The value status is returned to the parent process as the process’s exit status, and can be collected using one of the wait(2) family of calls.
The function _Exit() is equivalent to _exit().
exit()について:
#include
void exit(int status);
DESCRIPTION The exit() function causes normal process termination and the value of status & 0377 is returned to the parent (see wait(2)).
All functions registered with atexit(3) and on_exit(3) are called, in the reverse order of their registration. (It is possible for one of these functions to use atexit(3) or on_exit(3) to register an addi- tional function to be executed during exit processing; the new regis- tration is added to the front of the list of functions that remain to be called.) If one of these functions does not return (e.g., it calls _exit(2), or kills itself with a signal), then none of the remaining functions is called, and further exit processing (in particular, flush- ing of stdio(3) streams) is abandoned. If a function has been regis- tered multiple times using atexit(3) or on_exit(3), then it is called as many times as it was registered.
All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed.
The C standard specifies two constants, EXIT_SUCCESS and EXIT_FAILURE, that may be passed to exit() to indicate successful or unsuccessful termination, respectively.
exitと比較すると、exit()関数はstdlibに定義されています.h中、そして_exit()はunistdに定義する.hでは、
注:exit()は終了です.入力されたパラメータはプログラム終了時のステータスコードです.0は正常終了を表し、その他は非正常終了を表します.一般的には-1または1を使います.標準CにはEXIT_があります.SUCCESSとEXIT_FAILURE 2マクロ、exit(EXIT_SUCCESS);
_exit()関数の役割は最も簡単です.プロセスを直接停止させ、使用するメモリ領域を消去し、カーネル内の様々なデータ構造を破棄します.exit()関数は、これらに基づいていくつかのパッケージを作成し、終了を実行する前にいくつかの工程を追加します.exit()関数と_exit()関数の最大の違いは、exit()関数がexitシステム呼び出しを呼び出す前にファイルの開き具合をチェックし、ファイルバッファの内容をファイルに書き戻す「I/Oバッファのクリーンアップ」です.
exit()呼び出しプロセスを終了する前に、次の手順に従います.atexit()登録された関数(出口関数)を呼び出す.ATEXIT登録時とは逆の順序で登録するすべての関数を呼び出し、プログラム終了時に自分のクリーンアップ動作を実行するように指定することができる.例えば、プログラムの状態情報をあるファイルに保存する、共有データベースへのロックなどを解除する.
2.cleanup();開いているすべてのストリームを閉じると、バッファリングされたすべての出力が書き込まれ、TMPFILE関数で作成するすべての一時ファイルが削除されます.
3.最終呼び出し_exit()関数はプロセスを終了します.
_exitは3つのことをします(man):1,Any open file descriptors belonging to the process are closed 2,any children of the process are inherited by process 1,init 3,the process's parent is sent a SIGCHLD signal
exitクリーンアップ作業が完了したら呼び出す_exitはプロセスを終了します.
三、atexit()
atexitは終了処理プログラムを登録することができ、ANSI Cは最大32個の終了処理プログラムを登録することができることを規定している.
終了ハンドラの呼び出しは登録順序とは逆です
#include
int atexit(void (*function)(void));
DESCRIPTION The atexit() function registers the given function to be called at nor- mal process termination, either via exit(3) or via return from the pro- gram’s main(). Functions so registered are called in the reverse order of their registration; no arguments are passed.
The same function may be registered multiple times: it is called once for each registration.
POSIX.1-2001 requires that an implementation allow at least ATEXIT_MAX (32) such functions to be registered. The actual limit supported by an implementation can be obtained using sysconf(3).
When a child process is created via fork(2), it inherits copies of its parent’s registrations. Upon a successful call to one of the exec(3) functions, all registrations are removed.
RETURN VALUE The atexit() function returns the value 0 if successful; otherwise it returns a non-zero value.
サンプル・プログラム:
実行結果:
forkが呼び出されると、サブプロセスは親プロセスが登録したatexitを継承します.
サンプル・プログラム:
実行結果:
atexitに登録されている関数の1つが正常に返されていないかkillされていない場合、後続の登録関数は実行されません.
サンプル・プログラム:
実行結果:
最後のfun 1が実行されなかったことがわかります
一、プロセス終了には5つの方法があります.
正常終了:
main関数からを返す
呼び出しexit 呼び出し_exit
異常終了:
呼び出しabort 信号によって終了する二、exitと_exitの違い:
についてexit():
#include
void _exit(int status);
#include
void _Exit(int status);
DESCRIPTION The function _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process’s par- ent is sent a SIGCHLD signal.
The value status is returned to the parent process as the process’s exit status, and can be collected using one of the wait(2) family of calls.
The function _Exit() is equivalent to _exit().
exit()について:
#include
void exit(int status);
DESCRIPTION The exit() function causes normal process termination and the value of status & 0377 is returned to the parent (see wait(2)).
All functions registered with atexit(3) and on_exit(3) are called, in the reverse order of their registration. (It is possible for one of these functions to use atexit(3) or on_exit(3) to register an addi- tional function to be executed during exit processing; the new regis- tration is added to the front of the list of functions that remain to be called.) If one of these functions does not return (e.g., it calls _exit(2), or kills itself with a signal), then none of the remaining functions is called, and further exit processing (in particular, flush- ing of stdio(3) streams) is abandoned. If a function has been regis- tered multiple times using atexit(3) or on_exit(3), then it is called as many times as it was registered.
All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed.
The C standard specifies two constants, EXIT_SUCCESS and EXIT_FAILURE, that may be passed to exit() to indicate successful or unsuccessful termination, respectively.
exitと比較すると、exit()関数はstdlibに定義されています.h中、そして_exit()はunistdに定義する.hでは、
注:exit()は終了です.入力されたパラメータはプログラム終了時のステータスコードです.0は正常終了を表し、その他は非正常終了を表します.一般的には-1または1を使います.標準CにはEXIT_があります.SUCCESSとEXIT_FAILURE 2マクロ、exit(EXIT_SUCCESS);
_exit()関数の役割は最も簡単です.プロセスを直接停止させ、使用するメモリ領域を消去し、カーネル内の様々なデータ構造を破棄します.exit()関数は、これらに基づいていくつかのパッケージを作成し、終了を実行する前にいくつかの工程を追加します.exit()関数と_exit()関数の最大の違いは、exit()関数がexitシステム呼び出しを呼び出す前にファイルの開き具合をチェックし、ファイルバッファの内容をファイルに書き戻す「I/Oバッファのクリーンアップ」です.
exit()呼び出しプロセスを終了する前に、次の手順に従います.atexit()登録された関数(出口関数)を呼び出す.ATEXIT登録時とは逆の順序で登録するすべての関数を呼び出し、プログラム終了時に自分のクリーンアップ動作を実行するように指定することができる.例えば、プログラムの状態情報をあるファイルに保存する、共有データベースへのロックなどを解除する.
2.cleanup();開いているすべてのストリームを閉じると、バッファリングされたすべての出力が書き込まれ、TMPFILE関数で作成するすべての一時ファイルが削除されます.
3.最終呼び出し_exit()関数はプロセスを終了します.
_exitは3つのことをします(man):1,Any open file descriptors belonging to the process are closed 2,any children of the process are inherited by process 1,init 3,the process's parent is sent a SIGCHLD signal
exitクリーンアップ作業が完了したら呼び出す_exitはプロセスを終了します.
三、atexit()
atexitは終了処理プログラムを登録することができ、ANSI Cは最大32個の終了処理プログラムを登録することができることを規定している.
終了ハンドラの呼び出しは登録順序とは逆です
#include
int atexit(void (*function)(void));
DESCRIPTION The atexit() function registers the given function to be called at nor- mal process termination, either via exit(3) or via return from the pro- gram’s main(). Functions so registered are called in the reverse order of their registration; no arguments are passed.
The same function may be registered multiple times: it is called once for each registration.
POSIX.1-2001 requires that an implementation allow at least ATEXIT_MAX (32) such functions to be registered. The actual limit supported by an implementation can be obtained using sysconf(3).
When a child process is created via fork(2), it inherits copies of its parent’s registrations. Upon a successful call to one of the exec(3) functions, all registrations are removed.
RETURN VALUE The atexit() function returns the value 0 if successful; otherwise it returns a non-zero value.
サンプル・プログラム:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void fun1()
{
printf("fun1 is called
");
}
void fun2()
{
printf("fun2 is called
");
}
int main(void)
{
printf("main function
");
atexit(fun1);
atexit(fun2);
atexit(fun1);
exit(EXIT_SUCCESS);
}
実行結果:
forkが呼び出されると、サブプロセスは親プロセスが登録したatexitを継承します.
サンプル・プログラム:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define ERR_EXIT(m) \
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}\
while (0)\
void fun1()
{
printf("fun1 is called
");
}
void fun2()
{
printf("fun2 is called
");
}
int main(void)
{
pid_t pid;
pid = fork();
atexit(fun1);
atexit(fun2);
atexit(fun1);
if(pid == -1)
ERR_EXIT("fork error");
if(pid == 0){
printf("this is child process
");
}
if(pid > 0){
printf("this is parent process
");
}
return 0;
}
実行結果:
atexitに登録されている関数の1つが正常に返されていないかkillされていない場合、後続の登録関数は実行されません.
サンプル・プログラム:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void fun1()
{
printf("fun1 is called
");
}
void fun2()
{
printf("fun2 is called
");
kill(getpid(),SIGINT);
}
int main(void)
{
printf("main function
");
if(signal(SIGINT,SIG_DFL) == SIG_ERR){
perror("signal error");
exit(EXIT_FAILURE);
}
atexit(fun1);
atexit(fun2);
atexit(fun1);
exit(EXIT_SUCCESS);
}
実行結果:
最後のfun 1が実行されなかったことがわかります