GNU/Linux >> Linux Esercitazione >  >> Linux

È sicuro eseguire il fork dall'interno di un thread?

Il problema è che fork() copia solo il thread chiamante e tutti i mutex contenuti nei thread figlio saranno bloccati per sempre nel figlio fork. La soluzione pthread era pthread_atfork() gestori. L'idea era che puoi registrare 3 gestori:un prefork, un gestore genitore e un gestore figlio. Quando fork() accade prefork viene chiamato prima del fork e dovrebbe ottenere tutti i mutex dell'applicazione. Sia il genitore che il figlio devono rilasciare rispettivamente tutti i mutex nei processi padre e figlio.

Questa non è la fine della storia però! Le biblioteche chiamano pthread_atfork per registrare gestori per mutex specifici della libreria, ad esempio Libc fa questo. Questa è una buona cosa:l'applicazione non può assolutamente conoscere i mutex detenuti da librerie di terze parti, quindi ogni libreria deve chiamare pthread_atfork per garantire che i propri mutex vengano ripuliti in caso di fork() .

Il problema è che l'ordine che pthread_atfork gestori vengono chiamati per librerie non correlate non è definito (dipende dall'ordine in cui le librerie vengono caricate dal programma). Quindi questo significa che tecnicamente può verificarsi un deadlock all'interno di un gestore di prefork a causa di una race condition.

Ad esempio, considera questa sequenza:

  1. Il thread T1 chiama fork()
  2. I gestori di prefork libc sono chiamati in T1 (ad es. T1 ora contiene tutti i lock libc)
  3. Successivamente, nel thread T2, una libreria di terze parti A acquisisce il proprio mutex AM, quindi effettua una chiamata libc che richiede un mutex. Questo si blocca, perché i mutex libc sono mantenuti da T1.
  4. Il thread T1 esegue il gestore prefork per la libreria A, che blocca in attesa di ottenere AM, che è detenuto da T2.

C'è il tuo deadlock e non è correlato ai tuoi mutex o codice.

Questo in realtà è successo su un progetto su cui ho lavorato una volta. Il consiglio che avevo trovato in quel momento era di scegliere la forcella o i fili ma non entrambi. Ma per alcune applicazioni probabilmente non è pratico.


È sicuro eseguire il fork in un programma multithread fintanto che sei molto attento al codice tra fork ed exec. È possibile effettuare solo chiamate di sistema rientranti (ovvero asincrone sicure) in tale intervallo. In teoria, non sei autorizzato a malloc o free lì, anche se in pratica l'allocatore Linux predefinito è sicuro e le librerie Linux hanno fatto affidamento su di esso Il risultato finale è che devi usa l'allocatore predefinito.


Linux
  1. Ottieni il percorso completo da Bash Script?

  2. Utilizzando il comando passwd dall'interno di uno script di shell

  3. Come estraggo un singolo pezzo di byte dall'interno di un file?

  4. Chiama una funzione dello spazio utente dall'interno di un modulo del kernel Linux

  5. fopen() è una funzione thread-safe in Linux?

Come accedere alla shell o eseguire comandi esterni da Vim

Mantieni i server CentOS 6 al sicuro da una nuova vulnerabilità OpenSSL

Come utilizzare la webmail da cPanel

Rileva il ballooning della memoria dall'interno della VM interessata

Come modificare la directory predefinita della nuova finestra dall'interno di tmux

Crea collegamenti simbolici NTFS dall'interno di Linux