2011-09-14 3 views
8

Supponendo che un thread chiama con successo pthread_mutex_lock, è ancora possibile che una chiamata a pthread_mutex_unlock in quello stesso thread avrà esito negativo? Se è così, puoi davvero fare qualcosa al riguardo e interrompere il thread?Come gestite i fallimenti di pthread_mutex_unlock?

if(pthread_mutex_lock(&m) == 0) 
{ 
    // got the lock, let's do some work 

    if(pthread_mutex_unlock(&m) != 0) // can this really fail? 
    { 
     // ok, we have a lock but can't unlock it? 
    } 
} 

Da this page, possibili errori per pthread_mutex_unlock() sono:

[EINVAL] Il valore specificato dal mutex non si riferisce ad un oggetto inizializzato mutex.

Se il blocco è riuscito, è improbabile che ciò fallisca.

[EAGAIN] Il mutex non poteva essere acquisito perché è stato superato il numero massimo di serrature ricorsive per mutex.

Davvero? Per sbloccare?

La funzione pthread_mutex_unlock() potrebbe non riuscire se:

[EPERM] Il thread corrente non possiede il mutex.

Di nuovo, se il blocco è riuscito, anche questo non dovrebbe verificarsi.

Quindi, i miei pensieri sono se c'è un blocco riuscito, quindi in questa situazione lo sblocco non dovrebbe mai fallire rendendo inutile il controllo degli errori e il successivo codice di gestione.

risposta

2

Dalla pagina man per pthread_mutex_unlock:

The pthread_mutex_unlock() function may fail if: 

EPERM 
The current thread does not own the mutex. 

These functions shall not return an error code of [EINTR]. 

Se si ritiene che la pagina man, sembrerebbe che il tuo caso l'errore non può accadere.

+0

Grazie, che è praticamente il mio pensiero pure. Ho aggiornato la domanda per spero di rendere più chiaro il motivo per cui lo sto chiedendo. Voglio resistere per vedere se riesco a ottenere qualsiasi altro input prima di accettare una risposta. –

2

Ben prima di piangere "vittoria". Ho finito su questa pagina cercando un motivo per cui uno dei miei programmi ha fallito su un pthread_mutex_unlock (su HP-UX, non Linux).

if (pthread_mutex_unlock(&mutex) != 0) 
    throw YpException("unlock %s failed: %s", what.c_str(), strerror(errno)); 

Questo mi è venuto meno, dopo molte milioni di esecuzioni felici. errno era EINTR, anche se ho appena scoperto che non dovrei controllare errno, ma piuttosto il valore di ritorno. Tuttavia, il valore restituito NON era 0. E posso provare matematicamente che in quel punto possiedo un blocco valido.

Quindi diciamo solo che la tua teoria è sotto stress, anche se è necessaria più ricerca ;-)

+0

Fantastico! o forse non eccezionale. :-) Questo è esattamente il tipo di feedback che sto cercando. Sei in grado di riprodurre questo errore o è stata una cosa sola? Sarebbe interessante sapere quale fosse il vero valore di ritorno dal momento che 'pthread_mutex_unlock()' non dovrebbe restituire 'EINTR', in 'errno' o in altro modo. –

+0

non sono stato in grado di riprodurlo.Ho corretto il mio logging per mostrare il valore di ritorno effettivo, invece di errno. La prossima volta che succede (spero di no) ti farò sapere che cosa era esattamente ;-) – geert3

+2

Piccolo aggiornamento: ho avuto episodi spuri di sblocchi non riusciti, valore di ritorno == 1, che significa "Non proprietario". Questo si è rivelato un bug molto sottile. I wrap tutti i miei blocchi in oggetti (distruttore sblocca). Questo è utile in quanto il blocco termina automaticamente insieme all'ambito dell'oggetto. In questa funzione stavo chiamando thread_exit(). La pagina man dice che non puoi usare le variabili automatiche dopo thread_exit(). Che è esattamente ciò che stava facendo il distruttore del mio oggetto di blocco (implicitamente chiamato AFTER thread_exit). – geert3