Domanda

Ho un programma che:

  • ha un thread principale (1) che avvia un thread del server (2) e un altro (4).
  • il thread del server (2) esegue un accetta (), quindi crea un nuovo thread (3) per gestire la connessione.

Ad un certo punto, thread (4) esegue un fork / exec per eseguire un altro programma che dovrebbe connettersi al socket che il thread (2) sta ascoltando. Occasionalmente questo fallisce o richiede un tempo irragionevolmente lungo ed è estremamente difficile da diagnosticare. Se straccio il sistema, sembra che il fork / exec abbia funzionato, l'accettazione è avvenuta, il nuovo thread (4) è stato creato .. ma non succede nulla in quel thread (usando strace -ff, il file per il pid pertinente è vuoto).

Qualche idea?

È stato utile?

Soluzione

Sono giunto alla conclusione che probabilmente era questo fenomeno:

http://kerneltrap.org/mailarchive/linux -kernel / 2008/8/15/2950234 / thread

poiché il bug è difficile da attivare sui nostri sistemi di sviluppo ma è generalmente segnalato dagli utenti che girano su grandi macchine condivise; anche l'applicazione biforcuta avvia una JVM, che a sua volta alloca molti thread. Il problema è anche associato al caricamento della macchina e all'ampio utilizzo della memoria (abbiamo una macchina con 128 Gb di RAM e i processi possono avere una dimensione di 10-100 G).

Ho letto il libro di pthreads di O'Reilly, che spiega pthread_atfork (), e suggerisce l'uso di un "genitore surrogato". processo biforcato dal processo principale all'avvio da cui vengono eseguiti i sottoprocessi. Suggerisce anche l'uso di un pool di thread pre-creato. Entrambi sembrano buone idee, quindi ne implementerò almeno uno.

Altri suggerimenti

Sembra una condizione di deadlock. Cerca le funzioni di blocco, come accetta (), il problema dovrebbe essere lì.

Riduci il codice alla dimensione più piccola possibile che ha ancora il comportamento e pubblicalo qui. O troverai la risposta o saremo in grado di rintracciarla.

A proposito - http://lists.samba.org/archive /linux/2002-February/002171.html sembra che il comportamento pthread per exec non sia ben definito e possa dipendere dal tuo sistema operativo.

Hai qualche codice tra fork ed exec? Questo potrebbe essere un problema.

Stai molto attento con più thread e fork. La maggior parte di glibc / libstdc ++ è thread-safe. Se un thread, diverso dal thread di fork, tiene un blocco quando il fork esegue il processo fork, erediterà i mutex nel loro stato di blocco corrente. Il nuovo processo non vedrà mai quei mutex sbloccati. Per ulteriori informazioni, consultare man pthread_atfork .

Ho appena avuto gli stessi problemi e alla fine ho scoperto che fork () duplica tutti i thread . Ora immagina, cosa fa il tuo programma dopo un fork () con tutti i thread che eseguono la doppia istanza ...

Le seguenti regole sono di " A Mini -guida per fork () e Pthreads " :

  

1- NON VUOI farlo.

     

2- Se hai bisogno di fork () allora:   quando possibile, fork () tutto il tuo   bambini prima di iniziare qualsiasi thread.   

Modifica: provato, fork () non duplica i thread.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top