Domanda

sono variabili 'booleane' thread-safe per la lettura e la scrittura da qualsiasi thread? Ho visto alcuni riferimenti newsgroup di dire che lo siano. Sono altri tipi di dati disponibili? (Tipi enumerati, brevi int forse?)

Sarebbe bello avere una lista di tutti i tipi di dati che possono essere letti in modo sicuro da qualsiasi thread e un altro elenco che può anche essere scritto in modo sicuro per in qualsiasi discussione, senza dover ricorrere a vari metodi di sincronizzazione.

È stato utile?

Soluzione

Si prega di notare che si può fare in sostanza tutto in Delphi unthreadsafe. Mentre gli altri citano problemi di allineamento su booleano questo in un modo nasconde il vero problema.

Sì, si può leggere un valore booleano in ogni thread e scrivere un valore booleano in ogni discussione se è correttamente allineato. Ma la lettura da un valore booleano si cambia non è necessariamente "thread-safe" in ogni caso. Diciamo che avete un valore booleano impostato su true quando hai aggiornato un numero in modo che un altro thread legge il numero.

if NumberUpdated then
begin
  LocalNumber = TheNumber;
end;

A causa ottimizzazioni del processore rende Thenumber possono essere letti prima NumberUpdated viene letto, in tal modo è possibile ottenere il vecchio valore di Thenumber eventhough aggiornati NumberUpdated scorso.

Aka, il codice può diventare:

temp = TheNumber;
if NumberUpdated the
begin
  LocalNumber = temp;
end;

secondo me, una regola di base del pollice:
"Legge sono thread-safe. Scrive non sono thread-safe."
Quindi, se avete intenzione di fare una scrittura proteggere i dati con la sincronizzazione in tutto il mondo si legge il valore, mentre la scrittura potrebbe potenzialmente verificarsi.
D'altra parte, se solo di leggere e scrivere un valore in un thread, allora è thread-safe. Così si può fare un grande pezzo di scrittura in una posizione temporanea, quindi sincronizzare un aggiornamento dei dati applicationwide.

Bonus Blurb:

La VCL non è thread-safe. Tenere tutta la modifica di roba ui nel thread principale. Mantenere la creazione di tutte le cose ui nel thread principale troppo.

Molte funzioni non sono thread sicuro sia, mentre altri sono, spesso dipende dalle chiamate WinAPI sottostanti.

Non credo che una "lista" sarebbe utile come "thread-safe" può significare un sacco di roba.

Altri suggerimenti

Questa non è una questione di tipi di dati che sono thread-safe, ma è una questione di cosa fare con loro. Senza bloccaggio nessuna operazione è thread-safe che prevede il caricamento di un valore, quindi modificarlo, quindi scrivere indietro. Incrementare o decrementare un numero, compensazione o l'impostazione di un elemento in un insieme - non sono tutti thread-safe

Esiste un certo numero di funzioni che consentono operazioni atomiche: incremento interbloccato, decremento interbloccato, e scambio interbloccato. Si tratta di un concetto comune, niente di specifico a Windows, x86 o Delphi. Per Delphi è possibile utilizzare le funzioni InterlockedFoo () della API di Windows, ci sono diversi involucri attorno a quelli troppo. O lascia la tua. Le funzioni di operare su numeri interi, in modo da poter avere atomica incremento, decremento e lo scambio di numeri interi (32 bit) con loro.

È inoltre possibile utilizzare assembler e prefisso ops con il prefisso di blocco.

Per ulteriori informazioni vedi anche questa domanda StackOverflow .

architettura a 32 bit, solo correttamente allineati 32 bit o meno tipi di dati devono essere considerati atomico. valori a 32 bit deve essere allineata 4 (indirizzo dei dati deve essere divisibile per quattro). Probabilmente non incorrere in interleaving a tale livello stretto, ma in teoria si potrebbe avere doppia, Int64 o esteso scrittura non-atomica.

Con multi-core di elaborazione RISC e la memoria cache nucleo separato essendo nel mix di un processore moderno, è non più il caso che qualsiasi linguaggio di alto livello 'banale' leggere o scrivere costrutto (o per quella materia molti volta upon-a-time 8086 assembly 'atomica' istruzioni) può essere considerata atomica. In effetti, a meno che un'istruzione assembler è specificamente progettato per essere atomica, probabilmente non è atomica - e che comprende la maggior parte dei meccanismi per la memoria legge. Anche un intero lungo leggere a livello assemblatore può essere danneggiato da una scrittura simultanea di un altro core che condivide la stessa memoria e con azioni di aggiornamento della cache asincroni a livello RISC processore. Ricordate che su un processore che comprende più core RISC, anche il montaggio istruzioni in linguaggio sono effettivamente solo le istruzioni di codice "di livello superiore"! Non sai mai quanto sono in corso di attuazione a livello di bit, e potrebbe non essere proprio quello che ti aspettavi se si stesse leggendo un vecchio manuale di assembler 8086 (single-core). Windows non fornisce nativo sistema operatori atomiche compatibili, e si farebbe bene ad utilizzare questi invece di fare alcuna ipotesi di base sulle operazioni atomiche.

Perché utilizzare gli operatori di Windows? Perché una delle prime cose che Windows non è stabilire quello che la macchina è che è in esecuzione su. Uno degli aspetti chiave assicura che ottiene giusto è quello che operazioni atomiche ci sono e come funzionano. Se si desidera che il codice funzioni anche in futuro su qualsiasi processore futuro, è possibile duplicare (e costantemente aggiornare) tutto questo sforzo nel proprio codice, o si può fare uso del fatto che Windows ha fatto tutto già in fase di avvio. E poi incorporato il codice necessario nella sua API in fase di esecuzione.

Leggi le pagine di MSDN su operazioni atomiche. L'API di Windows superfici questi per voi. Essi possono a volte sembrano goffo o goffo -. Ma sono a prova di futuro e saranno sempre funzionerà esattamente come scritto sulla scatola

Come faccio a sapere questo? Bene, perché se così non fosse - allora si sarebbe non essere in grado di eseguire Windows. Punto. Non importa che esegue il proprio codice.

Ogni volta che si scrive il codice, è sempre una buona idea per capire parsimonia e prendere in considerazione rasoio di Occam . In altre parole, se Windows già lo fa, e il codice ha bisogno di Windows per eseguire, quindi utilizzare ciò che Windows fa già, invece di provare molte soluzioni ipotetiche alternative e sempre più complesse che possono o non possono funzionare. Fare qualsiasi altra cosa è solo uno spreco di tempo (a meno che, naturalmente, che è ciò che siete in a).

Il codice di Indy contiene alcuni tipi di dati di sicurezza atomica / filetto in IdThreadSafe.pas:

  • TIdThreadSafeInteger
  • TIdThreadSafeBoolean
  • TIdThreadSafeString
  • TIdThreadSafeStringList e ancora un po '...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top