2010-04-28 20 views
6

Ho conosciuto per eoni che il modo in cui si utilizza una variabile condizione èPerché le variabili di condizione a volte si attivano erroneamente?

lock 
while not task_done 
    wait on condition variable 
unlock 

perché a volte le variabili di condizione spontaneamente svegliarlo. Ma non ho mai capito perché sia ​​così. In passato ho letto che è costoso creare una variabile di condizione che non ha quel comportamento, ma niente di più.

Quindi ... perché è necessario preoccuparsi di essere erroneamente svegliati durante l'attesa di una variabile di condizione?

risposta

3

Non è che la variabile di condizione si attivi erroneamente; la variabile di condizione si riattiva solo se è stata segnalata da un altro thread. Tuttavia, è possibile che nel momento in cui il thread è stato riprogrammato per l'esecuzione, qualche altro thread è già riuscito a catturare la risorsa su cui si stava aspettando, e quindi è necessario ricontrollare. Ad esempio, se un gruppo di thread x, y, z sono in attesa su una risorsa R che w era in precedenza in attesa, e x, y, z, w comunicano attraverso una variabile di condizione ... supponiamo che w sia fatto con R e segnali x , y, z. Quindi, x, y e z saranno tutti rimossi dalla coda di attesa e posizionati nel runqueue per essere programmati per l'esecuzione. Supponiamo che x sia programmato per primo ... quindi acquista R, quindi può essere messo in stop, e quindi y potrebbe essere programmato, e quindi quando y è in esecuzione, la risorsa R su cui y era precedentemente in attesa non è ancora disponibile , quindi è necessario andare a dormire di nuovo. Quindi z si riattiva e z rileva che R è ancora in uso, quindi z deve tornare di nuovo a dormire, ecc.

Se si dispone esattamente di due thread e la variabile di condizione viene condivisa tra solo i due di loro, a volte ci sono situazioni in cui va bene non eseguire quel controllo. Tuttavia, se vuoi rendere la tua applicazione dinamica e capace di scalare fino ad un numero arbitrario di thread, allora è bene avere l'abitudine (per non dire molto più semplice e meno preoccupante) di fare quel controllo extra come è richiesto in la maggior parte delle situazioni.

+0

Non va mai bene eseguire il controllo. Non vi è alcuna garanzia, anche con solo due thread, che la condizione sia vera quando il thread si riattiva. –

+1

@Nick, non è così. Se la condizione è che l'altro thread abbia rilasciato il mutex associato alla variabile condition (in modo tale che essenzialmente stai alternando l'esecuzione tra i due thread, avanti e indietro), allora è sicuro, perché non puoi svegliare e riacquisire il lock fino a quando il altro thread lo ha rilasciato. Certo che non è tutto ciò che è utile. –

+1

Penso che tu stia cercando di forzare un punto che non dovrebbe essere fatto. Non c'è davvero alcuna buona ragione per cui non dovresti ricontrollare il predicato. Anche se la condizione è condivisa con solo due thread, non ci sono garofani che il thread che sta aspettando non sarà spuratamente risvegliato. –

1

Thread can sveglia senza essere segnalati. Si chiama wake up spuria. Tuttavia, proprio per il momento perché si verificano è una domanda che sembra essere impantanata nella superstizione e nell'incertezza. I motivi che ho visto includono l'effetto collaterale del modo in cui le implementazioni di threading funzionano o l'aggiunta intenzionale per forzare i programmatori a utilizzare correttamente i loop anziché i condizionali attorno a wait.

+0

LOL - "intenzionalmente aggiunto per forzare i programmatori a utilizzare correttamente i loop anziché i condizionali attorno all'aspettare" - oh aspetta, stai scherzando, giusto? :-) Tu non sei! Era Apple, non è vero? !! –

+0

@Bert F: In realtà ho spesso desiderato una versione di Linux in grado di esercitare tutto ciò che POSIX può rovinare con un programma. Gli zoccoli sarebbero tornati leggibili da 'select' e quindi non avrebbero avuto nulla da leggere. 'write' restituirebbe risultati parziali il 50% delle volte. le variabili di condizione si svegliano spontaneamente. Eccetera. –

Problemi correlati