2012-07-05 7 views
6

Ho un po 'di codice su due sistemi in esecuzione kernel 2.4.20 e kernel 2.4.38. Entrambi hanno gcc 3.2.2 e glibc 2.3.2differenze pthread_create nel kernel linux 2.4.20 e 2.4.36

Sotto kernel 2.4.38, le maniglie pthread_t non vengono riutilizzati. In caso di carico intenso, l'applicazione si arresta in modo anomalo quando gli handle raggiungono lo 0xFFFFFFFF.

(sospettavo questo in primo luogo, perché l'applicazione si blocca in distribuzioni in cui utilizza una porta di rete, scanner i fili vengono creati per la gestione delle connessioni socket)

Questo semplice esempio ricrea il problema:

void* ThreadProc(void* param) 
{ 
    usleep(10000); 
    printf(" Thread 0x%x\n", (unsigned int)pthread_self()); 
    usleep(10000); 
    return NULL; 
} 

int main(int argc, char* argv[]) 
{ 
    pthread_t sThread; 

    while(1) 
    { 
     pthread_create(&sThread, NULL, ThreadProc, NULL); 
     printf("Created 0x%x\n", (unsigned int)sThread); 
     pthread_join(sThread, NULL); 
    }; 

    return 0; 
} 

Sotto 2.4.20:

Created 0x40838cc0 
    Thread 0x40838cc0 
    Created 0x40838cc0 
    Thread 0x40838cc0 
    Created 0x40838cc0 
    Thread 0x40838cc0 
...and on and on... 

Sotto 2.4.36:

Created 0x4002 
    Thread 0x4002 
    Created 0x8002 
    Thread 0x8002 
    Created 0xc002 
    Thread 0xc002 
...keeps growing... 

Come è possibile ottenere kernel 2.4.36 per riciclare le maniglie? Sfortunatamente non posso cambiare facilmente il kernel. Grazie!

+1

Saluti al passato! Non penso che dipendere dal tuo programma su un comportamento del kernel di questo tipo sia una buona idea, dovresti piuttosto aggiustare il tuo programma. – PlasmaHH

+0

@PlasmaHH: il programma va bene; 'pthread_join' dovrebbe rilasciare tutte le risorse del thread. Il problema è che, in quella particolare versione del kernel, apparentemente non lo è. –

+0

@ MikeSeymour: cosa ti fa pensare? Per me sembra che stia distribuendo una maniglia diversa ogni volta, qualcosa che è perfettamente a posto, anche quando la maniglia precedente è stata liberata. Proprio come a = malloc (5); free (a); a == malloc (5); non deve essere vero – PlasmaHH

risposta

4

Se le tue osservazioni sono corrette, esistono solo due possibili soluzioni.

In entrambi i

  1. aggiornare il kernel. Questo potrebbe essere o non essere fattibile per te.
  2. Riciclare i fili all'interno dell'applicazione.

L'opzione 2 è qualcosa che puoi fare anche se il kernel non funziona correttamente. Puoi tenere un pool di thread che rimangono in uno stato dormiente quando non vengono utilizzati. I pool di thread sono uno schema di progettazione software ampiamente noto (vedere http://en.wikipedia.org/wiki/Thread_pool_pattern). Questa è probabilmente la soluzione migliore per te.

+1

C'è sempre '3. back-port una correzione da una versione futura del kernel e ricompilare il proprio kernel ' –

+0

@Kevin A. Naudé: Sì, probabilmente dovrò implementare un pool di thread. Spero ancora che qualcuno sappia una soluzione semplice per il kernel 2.4.36. Come ho già detto, non posso cambiare facilmente il kernel. (incluso creare il mio) – Scott

+0

@Scott: Se non riesci nemmeno a creare un kernel con patch che corregge il problema, non hai alcuna speranza di riparare il kernel. Sembra che la condivisione dei thread potrebbe essere la soluzione migliore (forse solo). –

0

Risulta che non ero unendo le mie discussioni correttamente nel test di carico.

Quando ho eseguito nuovamente il test di caricamento, le maniglie del thread hanno raggiunto 0xFFFFF002, quindi sono state spostate su 0x1002 e proseguite senza problemi.

Morale della trama: rendi morti sicuri che i tuoi fili siano uniti o distaccati!