La libreria standard C++ 11 è ampiamente thread-safe. Le garanzie di sicurezza delle filettature sugli oggetti PRNG sono le stesse dei contenitori. Più in particolare, poiché le classi PRNG sono tutte pseudo -random, ovvero generano una sequenza deterministica basata su uno stato corrente definito, non c'è davvero spazio per sbirciare o colpire qualcosa al di fuori dello stato contenuto (che è anche visibile a l'utente).
Proprio come i contenitori necessitano di blocchi per renderli sicuri da condividere, è necessario bloccare l'oggetto PRNG. Questo lo renderebbe lento e non deterministico. Un oggetto per thread sarebbe migliore.
1 Questa sezione specifica i requisiti che devono soddisfare le implementazioni per evitare corse di dati (1.10). Ogni funzione di libreria standard deve soddisfare ogni requisito, se non diversamente specificato. Le implementazioni possono impedire le corse di dati in casi diversi da quelli specificati di seguito.
2 A C++ funzione della libreria standard non deve direttamente o indirettamente oggetti di accesso (1,10) accessibili da fili diversi dalla corrente filo meno che gli oggetti sono accessibili direttamente o indirettamente tramite gli argomenti della funzione , incluso questo.
3 Una funzione libreria standard C++ non direttamente o indirettamente modificare oggetti (1.10) accessibile da fili diversi dalla corrente filo meno che gli oggetti sono accessibili direttamente o indirettamente tramite gli argomenti const non della funzione , incluso questo.
4 [Nota: Questo significa, per esempio, che le implementazioni non possono utilizzare un oggetto statico per scopi interni senza sincronizzazione perché potrebbe provocare una corsa dati anche in programmi che non condividono esplicitamente oggetti betweenthreads. -endnote] funzione della libreria standard
5 A C++ non deve accedere agli oggetti indirettamente accessibili tramite suoi argomenti o tramite elementi del suo contenitore argomenti tranne per funzioni richieste dalla specifica su tali elementi contenitori invocando.
6 Le operazioni su iteratori ottenuti chiamando una libreria standard funzione del contenitore o della stringa possono accedere al contenitore sottostante, ma non devono essere modificati. [Nota: in particolare, le operazioni del contenitore che invalidano gli iteratori sono in conflitto con le operazioni sugli iteratori associati a tale contenitore. - end note]
7 Le implementazioni possono condividere i propri oggetti interni tra i fili se gli oggetti non sono visibili agli utenti e sono protetti dalle corse di dati .
8 Salvo diversa indicazione, le funzioni di libreria standard C++ devono eseguire tutte le operazioni esclusivamente all'interno del thread corrente se quelle operazioni hanno effetti visibili (1.10) per gli utenti.
9 [Nota: questo consente alle implementazioni di parallelizzare le operazioni se non ci sono effetti collaterali visibili. - end note]
Questo è in pratica quello che ho pensato che non fosse thread-safe. Va bene condividere l'oggetto distribuzione 'std :: uniform_real_distribution zeroToOne (0.0, 1.0)' importo thread e utilizzare un motore per thread? –
user1139069
@ user1139069: No, non sicuro. Sebbene a prima vista un oggetto di distribuzione * possa * svolgere il suo compito semplicemente delegando ogni chiamata all'oggetto motore, senza mantenere lo stato interno, se ci pensate un motore che non produce abbastanza bit casuali potrebbe dover essere chiamato due volte. Ma due volte (o una volta) può essere eccessivo, quindi potrebbe essere meglio consentire il caching di bit casuali in eccesso. §26.5.1.6 \t "Requisiti di distribuzione numeri casuali" consente questo; gli oggetti di distribuzione hanno specificatamente lo stato che cambia con ogni chiamata. Pertanto dovrebbero essere trattati come parte del motore per scopi di blocco. – Potatoswatter