2011-01-07 12 views
9

Quando ho detto atomico, intendevo che l'insieme di istruzioni verrà eseguito senza alcun cambio di contesto in un'altra discussione sullo stesso processo (altri tipi di interruttori devono essere fatti ovviamente). L'unica soluzione che ho trovato è quella di sospendere tutti i thread tranne che attualmente eseguiti prima della parte e riprenderli dopo di essa. Qualunque modo più elegante?È possibile creare un pezzo di codice atomico (C#)?

Il motivo per cui desidero farlo è raccogliere uno stato coerente di oggetti in esecuzione su più thread. Tuttavia, il loro codice non può essere modificato (sono già compilati), quindi non posso inserire mutex, semafori, ecc. L'operazione atomica è ovviamente raccolta di stati (cioè copia di alcune variabili).

+1

Cosa stai cercando di ottenere? Sospendere tutti gli altri thread è un modo pericoloso per andare su cose e si potrebbe finire con un deadlock in cui il thread sveglio cerca di fare qualcosa e uno dei thread sospesi ha una sorta di blocco che non può mai rilasciare. –

+0

Non ho mai sentito la parola atomica in questo contesto. Lo so solo come parte di ACID, la definizione di una transazione. A proposito, perché hai bisogno di questo? –

+0

Le singole operazioni IL sono atomiche. Ci sono poche classi (una è Interlock) che supportano le operazioni atomiche. A parte questo, no. E non vedo il punto. – Amy

risposta

4

ci sono alcune operazioni atomiche nella classe Interlocked ma fornisce solo poche operazioni molto semplici. Non può essere utilizzato per creare un intero blocco atomico di codice.

Si consiglia di utilizzare il blocco con attenzione per assicurarsi che il codice funzioni anche se il contesto cambia.

1

Bene, è possibile utilizzare locks, ma non è possibile impedire esattamente il cambio di contesto. Ma se i tuoi thread si bloccano sullo stesso oggetto, i thread in attesa ovviamente non saranno in esecuzione, quindi non è necessario il cambio di contesto poiché non c'è niente da eseguire.

Anche tu potresti voler dare un'occhiata allo this page.

+0

I blocchi non necessariamente "senza alcun contesto che passa a un altro thread sullo stesso processo" –

+0

Sì, ho capito che in seguito; fatto un piccolo cambiamento, ma credo che ancora non risponda bene alla domanda. – Mehrdad

-1

No. È possibile circondare un blocco di codice con un monitor per renderlo thread-safe, ma non è possibile rendere atomici i frammenti di codice generici.

object lck = new object(); 

lock(lck) 
{ 
    // thread safe code goes in here 

} 
+0

Perché questo è downvoted? La mia risposta è in qualche modo errata? – Amy

+0

@ yodaj007: Non sono stato io a declassare, ma ho una supposizione sul perché: il tuo codice (se copiato ciecamente e incollato) creerà un nuovo oggetto ogni volta che viene eseguito e quindi non sincronizzerà nulla. –

+0

Ugh. Sì, questo è vero, il modo in cui l'ho digitato. Tuttavia non è stato copiato/incollato alla cieca. L'ho digitato in Notepad ++. – Amy

0

No, è contro il multi-tasking.

A meno che non siano operazioni molto semplici come l'incremento ... che non sono soggette alla tua domanda.

+1

L'incremento di un numero non è atomico a meno che non si parli della classe Interlocked. Posso fornire il codice per dimostrarlo, se lo si desidera; fai una domanda su SO e ti risponderò. – Amy

+0

Ho parlato in generale, e queste semplici operazioni sono come 'Interlocked.Increament()' e altre ancora. – Xaqron

0

È possibile ottenere uno stato globale da una memoria condivisa composta da una raccolta (array) di registri atomici di un lettore/multi scrittore. La soluzione è semplice ma non banale. Puoi leggere l'algoritmo pubblicato nel documento "istantanee atomiche della memoria condivisa" oppure puoi leggere il capitolo 4 dall'arte del libro di programmazione multiprocessore, lì puoi avere idee sull'implementazione sul linguaggio java, ovviamente, una volta che sei familiarizzato con l'idea dovresti essere in grado di trasportarlo in qualsiasi altra lingua. Scusa se il mio inglese non sta abbastanza bene.