2009-12-28 6 views
70

Qualcuno può spiegare semplicemente quale conflitto di thread è?Che cos'è il conflitto di thread?

L'ho cercato su google, ma non riesco a trovare una spiegazione semplice.

+6

Quindi scrivi il tuo vago pensiero su di esso, in modo che possiamo vedere dove potresti essere fuori, o la tua comprensione potrebbe essere corretta. –

risposta

56

La contesa del thread è essenzialmente una condizione in cui un thread è in attesa di un blocco/oggetto attualmente trattenuto da un altro thread. Pertanto, questo thread in attesa non può utilizzare quell'oggetto finché l'altro thread non ha sbloccato quell'oggetto particolare.

+30

Questa risposta è incompleta (come la maggior parte delle altre). Mentre un lucchetto è un tipo di cosa su cui può essere contesa, non è l'unica cosa del genere. Ci può essere contesa anche per le risorse senza serratura. Ad esempio, se due thread continuano a incrementare atomicamente lo stesso numero intero, potrebbero verificarsi conflitti a causa del ping-pong della cache. Nessun blocco è coinvolto. –

+0

Nel caso di un Global Interpreter Lock (GIL) come in CPython, dove thread deve sempre acquisire GIL, più thread in esecuzione nello stesso processo sono quindi in conflitto per impostazione predefinita. –

+0

Penso che tu l'abbia spiegato in termini di deadlock ma è molto diverso dal deadlock. –

1

Un'altra parola potrebbe essere la concorrenza. È semplicemente l'idea di due o più thread che cercano di utilizzare la stessa risorsa.

2

Hai 2 fili. Thread A e Thread B, hai anche l'oggetto C.

A sta attualmente accedendo all'oggetto C e ha posizionato un blocco su quell'oggetto. B deve accedere all'oggetto C, ma non può farlo fino A rilascia il blocco sull'oggetto C.

16

Da here:

Una contesa si verifica quando un filo è attesa di una risorsa che non è già disponibile; rallenta l'esecuzione del codice , ma può cancellare nel tempo.

Un deadlock si verifica quando un filo è attesa di una risorsa che un secondo thread è bloccato, e la seconda thread è in attesa di una risorsa il primo thread è bloccato. Più di due thread possono essere coinvolti in un deadlock . Lo stallo non risolve mai lo stesso . Spesso provoca l'arresto dell'intera applicazione o della parte che è verificata la situazione di stallo ( ).

+0

Questo spiega anche la differenza tra thread Contention e deadlock – Sankalp

125

Diverse risposte sembrano concentrarsi sulla contesa del blocco, ma i blocchi non sono le sole risorse su cui si può verificare la contesa. La contesa è semplicemente quando due thread tentano di accedere alla stessa risorsa o alle risorse correlate in modo tale che almeno uno dei thread contendenti venga eseguito più lentamente di quanto sarebbe se gli altri thread non fossero in esecuzione.

L'esempio più ovvio di contesa è su un lucchetto. Se il thread A ha un lock e il thread B vuole acquisire lo stesso lock, il thread B dovrà attendere che il thread A rilasci il lock.

Ora, questo è specifico della piattaforma, ma il thread potrebbe subire rallentamenti anche se non deve mai attendere che l'altro thread rilasci il blocco! Questo perché un lucchetto protegge alcuni tipi di dati, e spesso i dati stessi saranno contesi.

Ad esempio, considerare un thread che acquisisce un blocco, modifica un oggetto, quindi rilascia il blocco e fa alcune altre cose. Se due thread stanno facendo questo, anche se non combattono mai per il lock, i thread possono essere eseguiti molto più lentamente di quanto farebbero se fosse in esecuzione un solo thread.

Perché? Supponiamo che ogni thread funzioni sul proprio core su una moderna CPU x86 e che i core non condividano una cache L2. Con un solo thread, l'oggetto può rimanere nella cache L2 per la maggior parte del tempo. Con entrambi i thread in esecuzione, ogni volta che un thread modifica l'oggetto, l'altro thread troverà i dati non nella sua cache L2 perché l'altra CPU ha invalidato la riga della cache.Su un Pentium D, ad esempio, ciò farà sì che il codice funzioni alla velocità dell'FSB, che è molto inferiore alla velocità della cache L2.

Poiché il conflitto può verificarsi anche se il blocco non viene considerato valido, il conflitto può verificarsi anche in assenza di blocco. Ad esempio, supponiamo che la tua CPU supporti un incremento atomico di una variabile a 32 bit. Se un thread continua ad incrementare e decrementare una variabile, la variabile sarà molto calda nella cache per la maggior parte del tempo. Se due thread lo fanno, le loro cache contenderanno la proprietà della memoria che contiene quella variabile, e molti accessi saranno più lenti man mano che il protocollo di coerenza della cache opera per proteggere ogni proprietà principale della linea della cache.

Ironia della sorte, i blocchi in genere ridurre la contesa. Perché? Perché senza un blocco, due thread potrebbero operare sullo stesso oggetto o raccolta e causare molti conflitti (ad esempio, esistono code senza blocco). I blocchi tenderanno a deschedule i thread in conflitto, consentendo invece l'esecuzione di thread non contendenti. Se il thread A contiene un lock e il thread B vuole quello stesso lock, l'implementazione può eseguire il thread C. Se il thread C non ha bisogno di quel blocco, la contesa futura tra i thread A e B può essere evitata per un po '. (Ovviamente, questo presuppone che ci siano altri thread che potrebbero essere eseguiti. Non sarà di aiuto se l'unico modo in cui il sistema nel suo complesso può fare progressi utili è l'esecuzione di thread che contendono.)

+2

+1 Inoltre, solo per rendere esplicito, le due variabili su cui stanno combattendo due core non hanno nemmeno bisogno di essere la stessa variabile per causare contesa, devono solo essere memorizzate in memoria nella stessa riga della cache. Riempire le strutture e/o allineare le strutture alla memoria può aiutare a evitare questa forma di contesa. –

+1

@David, per favore, aiutaci a capire l'ultimo para della tua risposta in maggior dettaglio –

+3

@Naroji Fai una domanda al riguardo. –

1

Per me la contesa è una competizione tra 2 o più thread su una risorsa condivisa. La risorsa può essere un lucchetto, un contatore, ecc. Concorrenza significa "chi ottiene per primo". Più thread più contesa. Più frequente è l'accesso a una risorsa, maggiore è la contesa.

2

penso che ci dovrebbe essere qualche chiarimento da parte della OP sullo sfondo della questione - mi viene in mente 2 risposte (anche se sono sicuro che ci sono aggiunte a questa lista):

  1. se si riferiscono al "concetto" generale di conflitto di thread e come può presentarsi in un'applicazione, rimando alla risposta dettagliata di @ DavidSchwartz sopra.

  2. Esiste anche il contatore delle prestazioni "Blocchi e vincoli CLR .NET: Total # of Contentions". Come indicato dalla descrizione PerfMon per questo contatore, è definito come:

    Questo contatore visualizza il numero totale di volte in cui i thread nel CLR hanno tentato di acquisire un blocco gestito senza successo. Le serrature gestite possono essere acquisite in molti modi; con l'istruzione "lock" in C# o chiamando System.Monitor.Enter o usando l'attributo personalizzato MethodImplOptions.Synchronized.

... e sono sicuro che gli altri per altre OS'es e framework applicativi.

0

La contesa del thread influisce anche sulle operazioni di I/O. Esempio quando un thread in attesa di lettura del file può essere considerato come una contesa. Utilizzare le porte di completamento I/O come soluzione.

0

Il conflitto di blocco si verifica quando un thread tenta di acquisire il blocco su un oggetto che è già acquisito da altro thread *. Finché non viene rilasciato l'oggetto , il thread è bloccato (in altre parole, è nello stato di attesa ). In alcuni casi, ciò potrebbe portare a una cosiddetta esecuzione seriale che influisce negativamente sull'applicazione.

da dotTrace documentation

0

Immaginate il seguente scenario. Ti stai preparando per la finale di domani esaminare e sentirsi un po 'affamato. Quindi, dai a tuo fratello minore dieci dollari e chiedigli di comprare una pizza per te. In questo caso, sei il thread principale e tuo fratello è un thread secondario. Una volta che il tuo ordine è dato, sia tu che tuo fratello fate contemporaneamente il loro lavoro (cioè, studiando e comprando una pizza). Ora, abbiamo due casi da considerare su . Per prima cosa, tuo fratello ti riporta la pizza e termina mentre stai studiando. In questo caso, puoi smettere di studiare e divertirti con la pizza . In secondo luogo, finisci il tuo studio presto e dormi (cioè, il tuo lavoro assegnato per oggi - studio - studio per l'esame finale di domani - è fatto) prima che la pizza sia disponibile. Certo, non puoi dormire; altrimenti, non avrai la possibilità di mangiare la pizza. Quello che stai per fare è aspettare che tuo fratello porti indietro la pizza.

Come nell'esempio, i due casi danno un significato di rivalità.

Problemi correlati