2011-12-27 22 views
5

Cosa c'è di meglio:
avere un'ampia area di codice in istruzione lock
o
ad avere piccole serrature in un'ampia area ..
scambi in questo campione non sono changable? .Qual è il modo corretto per bloccare zone di codice

lock (padLock) 
{ 
    foreach (string ex in exchanges) 
    { 
    sub.Add(x.ID, new Subscription(ch, queue.QueueName, true)); 
......... 
} 

o

foreach (string ex in exchanges) 
{ 
    lock (padLock) 
    { 
    sub.Add(x.ID, new Subscription(ch, queue.QueueName, true)); 
    } 
..... 
+2

Dipende completamente da cosa si sta bloccando. – SLaks

+0

@SLaks, penso di non capire bene quando usare il blocco quindi .. :( – 0x49D1

+1

Il tuo esempio non è completo quindi non ha senso nella portata della domanda poiché né 'ex' né' exchange' non vengono usati in loop, quindi Difficile suggerirti qualcosa di concreto – sll

risposta

1

Il blocco più ampio - meno si ottiene dal multithreading e viceversa Quindi, l'uso dei blocchi dipende completamente dalla logica. Bloccare solo cose e luoghi che cambiano e devono correre da un solo filo in un tempo

Se si blocca per l'utilizzo della raccolta sub - utilizzare il blocco più piccolo, ma se si eseguono più simultanee foreach loop in parallelo

1

buona pratica sarebbe quella di bloccare solo quella zona che si desidera essere eseguita da un solo thread in un dato momento

Se quella zona è tutta ciclo foreach poi primo approccio va bene

ma se quell'area è solo una linea come hai mostrato io secondo approccio poi vai per il secondo approccio

1

In In questo caso particolare, l'opzione migliore è la prima, perché altrimenti si sta solo perdendo il blocco/lo sblocco del tempo poiché è comunque necessario eseguire l'intero ciclo. Quindi non ci sono molte opportunità per il parallelismo in un ciclo che esegue comunque operazioni atomiche individuali.

Per ulteriori consigli generali sulle dimensioni sezione critica controllare questo articolo: http://software.intel.com/en-us/articles/managing-lock-contention-large-and-small-critical-sections/

0

Non si può giudicare in modo efficace, che è "giusto" con il dato frammenti di codice. Il primo esempio dice che non è OK per le persone vedere sub con solo una parte del contenuto degli scambi. Il secondo esempio dice che è OK per le persone vedere sub con solo una parte del contenuto degli scambi.

1

Penso che ci siano due domande diverse:
1. Quale sarebbe corretto?
2. Quale potrebbe offrire prestazioni migliori?

La domanda sulla correttezza è complicata. Dipende dalle strutture dei dati e da come intendi il lucchetto per proteggerli. Se l'oggetto "sub" non è thread-safe, hai sicuramente bisogno del blocco grande.

La domanda sul rendimento è più semplice e meno importante (ma per qualche ragione, penso che tu ti concentri maggiormente su di esso).
Molte piccole serrature possono essere più lente, perché fanno solo più lavoro. Ma se riesci a eseguire una grande porzione del codice di loop senza bloccare, ottieni una certa concorrenza, quindi sarebbe meglio.

+0

grazie per la bella spiegazione. Ive ha inserito i loop con le raccolte non thread safe in lock come fatto con alcuni blocchi di codice che contengono le modifiche della collezione. La cosa sbagliata nella dichiarazione di blocco di grandi dimensioni per me qui era che il blocco conteneva anche alcuni metodi della stessa classe e utilizzava lo stesso oggetto di sincronizzazione. Quindi, penso, a volte questo porta a deadlock (o blocchi non proprio necessari) nel programma in esecuzione :(Dopo tutto il programma di modifiche è più reattivo ora. – 0x49D1

Problemi correlati