2012-04-21 7 views
5

Sto usando pthread_mutex_trylock per bloccare il mutex su una struttura in modo che sia possibile accedervi/modificarlo solo da un singolo thread in un dato momento. Se il mutex è già bloccato, torno dalla routine piuttosto che fare la coda/bloccare.Blocchi `pthread_mutex_trylock` quando chiamati da due thread allo stesso tempo

Si tratta di una struttura di base del mio codice:

typedef struct { 
    pthread_mutex_t m; 
} myStruct; 

void setupStruct(myStruct* struc) { 
    pthread_mutex_init(&struc->m, NULL); 
} 

void structOp(myStruct* struc) { 

    printf("structOp(): Trying to lock\n"); 

    if(pthread_mutex_trylock(&struc->m) != 0) { 
     printf("structOp(): Lock failed\n"); 
     return; 
    } else { 
     printf("structOp(): Locked\n"); 
     // do some stuff to struct 
     pthread_mutex_unlock(&struc->m); 
    } 
} 

La struct viene inizializzata una volta come questo:

myStruct* struc = malloc(sizeof(struc)); 
setupStruct(struc); 

Tuttavia, a volte, quando due thread chiamano una routine allo stesso tempo entrambe le chiamate a trylock sembra bloccare. Presumo questo perché stampa "Tentativo di blocco" per entrambi i thread contemporaneamente, ma non stampa se il mutex è stato bloccato o meno. Inizialmente avevo questo problema con pthread_mutex_lock quindi ho provato la versione non bloccante per questo motivo, ma sembra ancora bloccarsi.

Questo non accade sempre ma quando lo fa è sempre il prime due chiamate alla routine. Se le prime due chiamate funzionano correttamente, anche le chiamate successive funzionano correttamente.

C'è qualche motivo per bloccare? Sto percependo erroneamente questo blocco a causa di qualche altro problema? Posso pubblicare altre parti del mio codice se il problema potrebbe risiedere altrove.

+1

non v'è alcuna ragione per questo per bloccare, per quanto ne so. Qualcosa probabilmente è sbagliato altrove. – Mat

+1

Che cosa chiama setupStruct()? Non è chiamato più di una volta, per caso? –

+0

Viene chiamato solo una volta, appena prima dell'avvio dei nuovi thread. Penso che se c'è un problema è molto probabile con il mio uso di puntatori. Questi sembrano corretti? Sto allocando la struct con 'myStruct * struc = malloc (sizeof (struc));'. Aggiornerò la domanda con queste informazioni – Matt

risposta

8

Questa linea è sbagliata:

myStruct* struc = malloc(sizeof(struc)); 

Non alloate memoria sufficiente, quindi probabilmente stai cestinare/riutilizzare la memoria in cui si accede mutex. Utilizzando sizeof(struc) alloca la memoria per il tipo di struc, e il tipo di struc è un myStruct*, quindi sei allocare memoria di sola sufficiente per contenere un puntatore (ielikely solo 4 o 8 byte)

Si dovrebbe fare

myStruct* struc = malloc(sizeof *struc); 

o

myStruct* struc = malloc(sizeof(myStruct)); 
+0

Wow, ho deciso di assegnare le mie strutture errate per molto tempo .. grazie per aver spiegato! – Matt

0

Questo è un tipo di problema di temporizzazione o di corruzione della memoria. In entrambi i casi non è correlato al codice che hai postato, quindi non c'è modo di rispondere a questa domanda.

Se il sistema operativo supporta valgrind, controllare l'app con i moduli memcheck e helgrind.