GNU/Linux >> Linux Esercitazione >  >> Linux

Qual è la differenza tra l'utilizzo di _exit() e exit() in un fork-exec Linux convenzionale?

Dovresti usare _exit (o il suo sinonimo _Exit ) per interrompere il programma figlio quando exec fallisce, perché in questa situazione, il processo figlio può interferire con i dati esterni (file) del processo padre chiamando il suo atexit gestori, chiamando i suoi gestori di segnale e/o svuotando i buffer.

Per lo stesso motivo, dovresti usare anche _exit in qualsiasi processo figlio che non esegue un exec , ma sono rari.

In tutti gli altri casi, usa semplicemente exit . Come hai in parte notato tu stesso, ogni processo in Unix/Linux (eccetto uno, init ) è il figlio di un altro processo, quindi usare _exit in ogni processo figlio significherebbe che exit è inutile al di fuori di 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() svuota i buffer io e fa altre cose come eseguire le funzioni registrate da atexit() . exit() invoca _end( )

_exit() termina semplicemente il processo senza farlo. Tu chiami _exit() dal processo padre durante la creazione di un demone, ad esempio.

Hai mai notato che main() è una funzione? Ti sei mai chiesto come lo chiami in primo luogo? Quando un programma c esegue la shell in cui stai eseguendo fornisce il percorso eseguibile alla chiamata di sistema 'exec' e il controllo viene passato al kernel che a sua volta chiama la funzione di avvio di ogni eseguibile _start() , chiama il tuo main() , quando main() lo restituisce quindi chiama _end() Alcune implementazioni di C usano nomi leggermente diversi per _end() &_start() ...

exit() e _exit() richiamare _end()

Normalmente - per ogni main() dovrebbe esserci uno e un solo exit() chiamata. (o ritorna alla fine di main() )


exit() è in cima a _exit(), usando la libreria C convenzionale.

Ci sono le differenze:

  1. _exit() non svuota il buffer stdio mentre exit() svuota il buffer stdio prima di uscire.

  2. _exit() non può eseguire il processo di pulizia mentre exit() può essere registrato con qualche funzione (ad esempio on_exit o at_exit) per eseguire un processo di pulizia se è necessario qualcosa prima dell'esistenza del programma.

exit(status) passa semplicemente lo stato di uscita a _exit(status). Si raccomanda che ogni volta che si esegue fork(), uno di essi tra figlio e genitore, uno usi _exit() e un altro usi exit().


Linux
  1. Qual è la differenza tra module_init e init_module in un modulo del kernel Linux?

  2. Qual è la differenza tra env e set (su Mac OS X o Linux)?

  3. Qual è la differenza tra memoria buffer e cache in Linux?

  4. Qual è la differenza tra l'uso di `sh` e `source`?

  5. Qual è la differenza tra un driver di piattaforma Linux e un normale driver di dispositivo?

Qual ​​è la differenza tra i kernel macOS e Linux

Qual è la differenza tra Linux e Unix?

Qual è la differenza tra Rsync e BTRFS in Linux?

Qual è la differenza tra l'installazione di un pacchetto usando pip e apt-get?

Qual è la differenza tra una chiamata di libreria e una chiamata di sistema in Linux?

Qual è la differenza tra unlink e rm?