Quanto sarebbe male ottenere un blocco su ogni oggetto?

-1

Immagina un ipotetico ambiente di programmazione che è in gran parte simile a Java o .NET, ovvero orientato agli oggetti, garbage-collected, ecc., ma con una piccola modifica:

Ogni volta che chiami un metodo su un oggetto, viene ottenuto un blocco in modo che nessun thread possa eseguire contemporaneamente i metodi sullo stesso oggetto. Il blocco viene abbandonato quando il metodo restituisce.

Anche il blocco viene temporaneamente abbandonato quando chiami Thread.Join (questo serve solo per prevenire determinati tipi di situazioni di deadlock).

Quanto sarebbe grave l'impatto sulle prestazioni di questo? Quanto questo potrebbe interferire con la concorrenza? Esistono algoritmi / programmi che sarebbe impossibile parallelizzare in questo tipo di ambiente?

Nella mia domanda postata in precedenza, è stato fornito un collegamento a questa pagina relativa a GIL in CPython che reclama prestazioni severe e problemi di concorrenza con questo. Tuttavia, afferma anche che questo ambiente utilizza il conteggio dei riferimenti e l'incremento / decremento di quel conteggio dei riferimenti è un'operazione che ottiene tale blocco. Non assumiamo quello; Il GC di .NET è mark-and-sweep, non conteggiato come riferimento.

    
posta Timwi 22.02.2013 - 03:07
fonte

2 risposte

7

Quasi sicuramente finirai con il thread singolo, perché ogni tentativo di multithread finirebbe in un deadlock!

GIL in Python evita i deadlock avendo un singolo lock su un singolo oggetto, un deadlock è semplicemente impossibile se un solo oggetto è bloccato.

Non appena si blocca su due o più oggetti è possibile una situazione di blocco morto. Un blocco su ogni oggetto renderebbe quasi impossibile una situazione di stallo.

    
risposta data 22.02.2013 - 03:25
fonte
0

tl; dr: l'impatto dipenderà da come vengono implementati i blocchi e da quanto accesso simultaneo hai effettivamente nel tuo programma. Questo risolve alcuni problemi di concorrenza, ma non tutti, quindi non ti assolve dalla comprensione e dal pensare a cosa sta succedendo nel tuo programma.

Se assumiamo un'implementazione di blocco veloce quando non contestata, l'impatto dipende in gran parte da quanta interazione cross-thread hai effettivamente. Non so voi, ma la maggior parte della mia programmazione concorrente finisce per essere "feed values to the other thread" e "consumare valori da un altro thread" - i punti di interazione tendono ad essere molto stretti.

Fuori mano Tendo a pensare che nella maggior parte dei casi non varrà la pena. Potresti pensare che salverà ogni sorta di caos tra i thread, ma risolverà solo una parte delle difficoltà di interazione tra thread.

Se segui questo modello, devi assicurarti che QUALSIASI cosa tu voglia fare a un oggetto possa essere espressa come una singola chiamata. Se non lo fai, allora l'oggetto può ancora essere in uno stato strano, anche con i blocchi.

Considerare, per un momento, un oggetto che contiene i dettagli di un contatto di una persona. Supponiamo che desideriamo aggiornare sia il numero di telefono che l'indirizzo e-mail. Se si dispone di un metodo per oggetto da aggiornare (setter semplici), anche se questi setter hanno blocchi, l'oggetto può comunque trovarsi in uno stato incoerente tra le chiamate per aggiornare il numero di telefono e l'e-mail.

L'unico modo per aggiornare in modo sicuro un tale oggetto è avere un modo per bloccare l'oggetto nel suo complesso (credo che Java faccia questo?), e rilasciarlo quando è fatto, OPPURE avere metodi "combinatori" che coprano qualsiasi insieme di aggiornamenti simultanei che vorrete fare.

Non sto dicendo che la tecnica non sia mai utile, ovviamente. Ma per problemi di programmazione media, sospetto che faccia più male di quanto non aiuti.

    
risposta data 22.02.2013 - 03:37
fonte

Leggi altre domande sui tag