Domanda

Mi chiedo quale sia il modo "migliore" per rendere thread-safe dei dati.

In particolare, ho bisogno di proteggere una lista collegata tra più thread - un thread potrebbe tentare di leggere da esso, mentre un altro thread aggiunge / rimuove i dati da esso, o persino libera l'intero elenco. Ho letto sui blocchi; che sembrano essere l'approccio più comunemente utilizzati, ma a quanto pare può essere problematico (deadlock). Ho anche letto su atomiche-operazioni, nonché archiviazione thread-locale.

Secondo te, quale sarebbe il mio miglior modo di agire? Qual è l'approccio che la maggior parte dei programmatori di utilizzare, e per quale motivo?

È stato utile?

Soluzione

Un approccio che non viene molto utilizzato, ma molto suono, è quello di designare una speciale filettatura scopo di possedere ogni struttura "condivisa". Quel filo siede generalmente attesa su un (;-) coda thread-safe, ad esempio in Python un'istanza Queue.Queue, per richieste di lavoro (lettura o la modifica della struttura condivisa), inclusi sia quelli che richiedono una risposta (che passerà la propria coda in cui la risposta è posto quando pronto) e quelli che non lo fanno. Questo approccio serializza completamente tutti gli accessi alla risorsa condivisa, rimappa facilmente ad un multi-processo o architettura distribuita (quasi Incredibilmente, in Python, con multiprocessing ;-), e assolutamente garantisce la solidità e la mancanza di deadlock, nonché condizioni di gara più a lungo l'oggetto di coda sottostante è ben programmato, una volta per tutte.

Si scopre praticamente l'inferno di strutture di dati condivise nel paradiso delle architetture concorrenza message-passing.

OTOH, è potrebbe essere un po 'più elevato sovraccarico rispetto slugging il modo rigido con lucchetti & c; -.)

Altri suggerimenti

Si potrebbe prendere in considerazione una collezione immutabile. Molto simile come una stringa in .net ha metodi come la Sostituzione, inserimento, ecc non modifica la stringa, ma invece ne crea una nuova, una raccolta LinkedList può essere progettato per essere immutabili pure. Infatti, un LinkedList è in realtà abbastanza semplice da implementare questo modo, rispetto ad altre strutture di dati raccolta.

Ecco un link ad un post sul blog discutendo collezioni immutabili e un link per alcune implementazioni in .NET.

http: / /blogs.msdn.com/jaredpar/archive/2009/04/06/immutable-vs-mutable-collection-performance.aspx

Ricordate sempre la regola più importante della sicurezza dei thread. Conoscere tutte le sezioni critiche del codice dentro e fuori. E con questo, li conoscono come i vostri ABC. Solo se è possibile individuare a andare una volta chiesto si può sapere quali sono le aree di operare i vostri meccanismi di sicurezza sul filo.

Dopo di che, ricordare le regole del pollice:

  • Look out per tutto il vostro globale Variabili / variabili sul mucchio.
  • Assicurarsi che le subroutine sono rientrante.
  • Assicurati che l'accesso ai dati condivisi è serializzato.
  • Assicurarsi che non vi siano indirette accessi tramite puntatori.

(sono sicuro che gli altri possono aggiungere di più.)

Il modo "migliore", dal punto di vista della sicurezza, è quello di mettere una serratura della intera struttura di dati, in modo che solo un thread può toccare alla volta.

Una volta che si decide di bloccare meno l'intera struttura, presumibilmente per motivi di prestazioni, i dettagli di questa operazione sono disordinati e si differenziano per ogni struttura di dati, e anche varianti della stessa struttura.

Il mio suggerimento è quello di

  1. Inizia con un blocco globale sulla struttura dei dati. Profilo vostro programma per vedere se è davvero un problema.

  2. Se è un problema, considerare se c'è qualche altro modo per distribuire il problema. Si può ridurre al minimo la quantità di dati nella struttura dati in questione, in modo che esso non deve essere letta così spesso o per così tanto tempo? Se si tratta di un sistema di coda, per esempio, forse è possibile mantenere una coda locale per thread, e muovere solo le cose all'interno o all'esterno di una coda globale quando una coda locale diventa sovra o sotto-caricato.

  3. Guarda le strutture dati progettati per aiutare a ridurre contesa per il particolare tipo di cosa si sta facendo, e la loro attuazione con cura e precisione, errare sul lato della sicurezza. Per l'esempio in coda, code di lavoro furto potrebbe essere quello che ti serve.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top