Měli byste použít _exit
(nebo jeho synonymum _Exit
) k přerušení podřízeného programu při exec
selže, protože v této situaci může podřízený proces zasahovat do externích dat (souborů) nadřazeného procesu voláním jeho atexit
handlery, volání jeho signálových handlerů a/nebo vyprázdnění bufferů.
Ze stejného důvodu byste měli použít také _exit
v žádném podřízeném procesu, který neprovádí exec
, ale ty jsou vzácné.
Ve všech ostatních případech stačí použít exit
. Jak jste si částečně všimli, každý proces v Unixu/Linuxu (kromě jednoho, init
) je potomkem jiného procesu, takže pomocí _exit
v každém podřízeném procesu by to znamenalo exit
je k ničemu mimo init
.
switch (fork()) {
case 0:
// we're the child
execlp("some", "program", NULL);
_exit(1); // <-- HERE
case -1:
// error, no fork done ...
default:
// we're the parent ...
}
exit()
vyprázdní vyrovnávací paměti io a provede některé další věci, jako je spouštění funkcí registrovaných atexit()
. exit()
vyvolá _end( )
_exit()
prostě ukončí proces, aniž by to udělal. Voláte _exit()
z nadřazeného procesu například při vytváření démona.
Všimněte si, že main()
je funkce? Přemýšleli jste někdy nad tím, co to vůbec nazval? Když program c spustí shell, ve kterém běžíte, poskytne spustitelnou cestu k systémovému volání 'exec' a řízení je předáno jádru, které zase zavolá spouštěcí funkci každého spustitelného _start()
, zavolá vaše main()
, když main()
vrátí jej a poté zavolá _end()
Některé implementace jazyka C používají mírně odlišné názvy pro _end()
&_start()
...
exit()
a _exit()
vyvolejte _end()
Normálně - za každých main()
měl by být jeden a pouze jeden exit()
volání. (nebo se vraťte na konec main()
)
exit() je na vrcholu _exit() pomocí konvenční knihovny C.
Rozdíly jsou:
-
_exit() nevyprázdní vyrovnávací paměť stdio, zatímco exit() vyprázdní vyrovnávací paměť stdio před ukončením.
-
_exit() nemůže provést proces čištění, zatímco exit() může být registrován s nějakou funkcí (tj. on_exit nebo at_exit), aby provedl nějaký proces čištění, pokud je před existencí programu cokoli vyžadováno.
exit(status) jednoduše předá stav ukončení do _exit(status). Doporučuje se, aby při každém provedení fork(), jeden z nich mezi potomkem a rodičem, jeden použil _exit() a druhý použil exit().