La funzione pthread_mutex_unlock() deve rilasciare l'oggetto mutex a cui fa riferimento mutex. Ma il modo in cui un mutex viene rilasciato dipende dall'attributo type del mutex. Se sono presenti thread bloccati sull'oggetto mutex a cui fa riferimento mutex quando viene chiamato pthread_mutex_unlock(), il risultato della mutex diventa disponibile, la politica di pianificazione determina quale thread acquisirà il mutex.
Se il tipo di mutex è PTHREAD_MUTEX_NORMAL, il rilevamento del deadlock non deve essere fornito. Il tentativo di bloccare il mutex provoca un deadlock. Se un thread tenta di sbloccare un mutex che non ha bloccato o un mutex che è sbloccato, si ottiene un comportamento indefinito.
Se il tipo di mutex è PTHREAD_MUTEX_ERRORCHECK, è necessario fornire un controllo degli errori. Se un thread tenta di ricollegare un mutex che ha già bloccato, verrà restituito un errore. Se un thread tenta di sbloccare un mutex che non ha bloccato o un mutex che è sbloccato, deve essere restituito un errore.
Se il tipo di mutex è PTHREAD_MUTEX_RECURSIVE, il mutex deve mantenere il concetto di un conteggio di blocco. Quando un thread acquisisce con successo un mutex per la prima volta, il conto di blocco deve essere impostato su uno. Ogni volta che un thread ricollega questo mutex, il conteggio dei blocchi deve essere incrementato di uno. Ogni volta che il thread sblocca il mutex, il numero di blocchi verrà decrementato di uno. Quando il conteggio dei blocchi raggiunge lo zero, il mutex diventa disponibile per altri thread da acquisire. Se un thread tenta di sbloccare un mutex che non ha bloccato o un mutex che è sbloccato, deve essere restituito un errore.
Se il tipo di mutex è PTHREAD_MUTEX_DEFAULT, il tentativo di bloccare in modo ricorsivo i risultati mutex nel comportamento non definito. Il tentativo di sbloccare il mutex se non è stato bloccato dal thread chiamante determina un comportamento indefinito. Il tentativo di sbloccare il mutex se non è bloccato determina un comportamento indefinito.
Di solito preferisco usare i mutex PTHREAD_MUTEX_RECURSIVE, perché in questo caso il mutex diventa disponibile quando il conteggio raggiunge lo zero e il thread chiamante non ha più blocchi su questo mutex.
Lo sblocco di un mutex può essere lento se c'è un sacco di contesa su quel mutex, perché parte del lavoro di sblocco sta svegliando qualsiasi thread in attesa sul mutex. – caf
Penso che sarebbe interessante vedere i risultati se si sposta la chiamata 'pthread_mutex_unlock()' sopra la chiamata a 'pthread_cond_signal()'. Non c'è alcun obbligo di tenere il mutex mentre segnala la variabile di condizione (solo quando lo si aspetta), e sospetto che ciò che accade sia che il segnale causi conflitto sul mutex perché il thread che viene rilasciato tenta immediatamente di acquisire il mutex, che il il filo di segnalazione rimane fermo. –
@MichaelBurr Buon punto! Esamino il tuo suggerimento e il programma è ora più veloce del 40%. –