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().