2012-09-29 19 views
6

Sto utilizzando il codice precedente per incrementare un contatore utilizzando 2 thread, che prendono in modo indipendente il blocco mut e il contatore di incremento. Sto affrontando un deadlock dopo che i thread entrano in questa funzione.pthread_mutex_lock causa deadlock

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; 

void *increment_counter(void *counter_addr) 
{ 
    int max = MAX_COUNTER_VALUE; 
    int iter; 
    int counter; 

    for(iter=0;iter< max ;iter++) 
    // LOCK 
    pthread_mutex_lock(&mut); 
    counter++; 
    // UNLOCK 
    pthread_mutex_unlock(&mut); 
    return NULL; 
} 

Qualcuno potrebbe dirmi dove esattamente sto sbagliando?

+2

probabilmente voleva 'int * contatore = counter_addr' e' ++ * counter'. –

risposta

10

Si sta tentando di bloccare il mutex max volte, quindi incrementare counter e rilasciarlo una volta.

Prova:

for(iter=0;iter< max ;iter++) 
{ 
    // LOCK 
    pthread_mutex_lock(&mut); 
    counter++; 
    // UNLOCK 
    pthread_mutex_unlock(&mut); 
} 
return NULL; 
+1

Ohh .. E 'stato un brutto errore di programmazione .. grazie per averlo indicato. :) –

3

che è forse quello che si è tentato di fare:

int max = MAX_COUNTER_VALUE; 
int iter; 
int counter; 
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; 

void *increment_counter(void *counter_addr) 


{ 

    pthread_mutex_lock(&mut);  
    for(iter=0;iter< max ;iter++) 
     counter++; 
    pthread_mutex_unlock(&mut); 
    return NULL; 
} 
  • 2 o più thread condividono i dati di portata solo globali o dati presenti sul heap (malloc) .
  • 2 o più thread non condividono le variabili definite nello stack questo dato è univoco per ogni thread e non è necessario bloccarlo.

Si sono accolti a leggere in the answers ciò che è condiviso e ciò che non è condiviso ecc

0

In linea di principio, lo stesso filo non deve bloccare un mutex più di una volta e questo è quello che è successo qui.

0

l'inizializzazione del blocco è molto importante. Se non si inizializzano i blocchi al valore corretto, il codice si interrompe. Un metodo per inizializzare il blocco è la seguente:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

Inoltre è possibile eseguire questa operazione in modo dinamico utilizzando il seguente codice:

int rc = pthread_mutex_init(&lock, NULL); 
assert(rc == 0); // always check success! 

Accanto inizializzazione di blocco, si dovrebbe verificare per il codice di ritorno di pthread_mutex_lock per vedere se fallisce o no come se fallisse, più thread possono entrare nella sezione critica. A questo scopo, è possibile utilizzare un codice simile a questo, che controlla per il codice di ritorno di pthread_mutex_lock:

// Use this to keep your code clean but check for failures 
// Only use if exiting program is OK upon failure 
void Pthread_mutex_lock(pthread_mutex_t *mutex) { 
int rc = pthread_mutex_lock(mutex); 
assert(rc == 0); 
}