2010-05-07 25 views
6

Ho un'applicazione che genererà più thread. Tuttavia, ritengo che potrebbe esserci un problema con i thread che accedono ai dati che non dovrebbero essere. Sono relativamente nuovo nel threading così nudo con me.Passaggio di strutture di dati a thread diversi

Ecco la struttura dell'applicazione filettato (spiacente per la grossolanità):

    MainThread 
       /  \ 
       /   \ 
       /   \ 
     Thread A    Thread B 
    /  \   /  \ 
    /  \   /  \ 
    /   \  /   \ 
Thread A_1  Thread A_2 Thread B_1 Thread B_2 

Sotto ogni lettered filo (che potrebbe essere molti), vi saranno solo due fili e vengono sparati sequenzialmente. Il problema che sto avendo è che non sono del tutto sicuro di come passare in una struttura dati in questi thread.

Quindi, la struttura dei dati viene creata in MainThread, verrà modificata nella stringa letterale (Thread A, ecc.) Specifica per quel thread e quindi una variabile membro da tale infrastruttura viene inviata ai thread Letter_Numbered.

Attualmente, la classe thread con lettere ha una variabile membro e quando la classe viene costruita, la struttura dati da mainthread viene passata per riferimento, richiamando il costruttore di copie in modo che il thread con lettere abbia la propria copia con cui giocare.

Il thread con numero di lettere contiene semplicemente una variabile stringa dalla struttura dati all'interno del thread con lettere. La mia domanda è, è accettabile? C'è un modo molto migliore per garantire che ogni thread con lettere abbia la propria struttura dati con cui giocare?

Siamo spiacenti per la spiegazione un po 'scarsa, si prega di lasciare commenti e proverò a chiarire.

MODIFICA: Quindi il mio costruttore di thread con lettere dovrebbe prendere il VALORE della struttura dati, non il riferimento?

+0

Forse parlaci un po 'di ciò che vuoi ottenere. Sono un po 'perplesso dall'uso di due thread sequenziali: vuoi dire che uno inizia quando l'altro finisce? – mdma

+0

+1 per la domanda ben articolata –

+0

@mdma: intendi il carattere numerato? Se è così allora sì, il thread con lettere si spegne il primo carattere numerato, attende che sia terminato (o errore) e spenga il secondo carattere numerato. Questo aiuta? – Robb

risposta

5

Vorrei che ogni thread creasse la propria copia del datastructure, ad es. si passa la struttura nel costruttore e quindi si crea esplicitamente una copia locale. Quindi sei garantito che i thread hanno copie distinte. (Dici che è passato per riferimento e che invoca il costruttore di copie, penso che intendi passare per valore? Sento che è meglio fare una copia in modo esplicito, non lasciare dubbi e rendere chiaro il tuo intento. vieni e modifica il tuo pass per valore per passare come riferimento come "ottimizzazione intelligente".)

MODIFICA: commento rimosso sulle stringhe. Per qualche ragione, stavo assumendo .NET.

Per garantire che le stringhe siano di proprietà privata, seguire la stessa procedura, creare una copia della stringa, che è quindi possibile modificare liberamente.

+0

Hmm, beh passiamo per riferimento ma invoca il costruttore di copie e sembra assegnare la variabile membro alla propria copia. Non l'ho ancora completamente verificato, potrebbe farlo oggi. – Robb

+3

Le stringhe in C++ non sono immutabili. – stonemetal

+0

Inoltre, assicurarsi che sia una copia profonda per assicurarsi che tutti i dati siano locali. Se riesci a cavartela senza condividere nulla tra i thread, questo è il modo più sicuro e semplice per farlo. –

1

Hai guardato boost threads?

Fondamentalmente si crea una classe chiamabile che ha un costruttore che accetta i parametri su cui deve lavorare il thread e quindi avvia il thread passando gli oggetti della classe Callable, inizializzati e pronti per l'esecuzione.

Questo è molto simile a come Java implementa i thread e ha un buon senso per la maggior parte del tempo dal punto di vista del design.

+0

Per quanto mi piacerebbe seguire il percorso di boost, il progetto è attualmente in uno stato in cui ciò richiederebbe una riscrittura sufficiente per essere abbattuto dai superiori. – Robb

+0

bene, anche se boost non è disponibile - supponendo che tu stia cominciando a lanciare thread tramite un metodo membro di un oggetto, il modello si applica ancora: crea una classe thread che abbia: - un costruttore che richiede tutti i dati che il thread deve lavorare su - un metodo di avvio/esecuzione che funge da punto di ingresso thread e ciclo di elaborazione Quindi si creano le istanze degli oggetti thread e quindi li si avvia passando il metodo start/run/any degli oggetti come il punto di ingresso del filo. – sechastain

+0

Sì, questo è in realtà ciò che faccio, tranne l'utilizzo del pass per riferimento della struttura dati. – Robb

3

V'è un modello chiamato Active Object Pattern cui ciascun oggetto viene eseguito nel proprio thread. Framework come ACE supportano questo. Se hai accesso a tali quadri, dovresti usarli.In ogni caso, credo che creare una nuova istanza di un oggetto e consentirgli di esetizzare nel proprio thread sia molto più pulito che invocare il copy-constructor per creare una copia dell'oggetto. Altrimenti vedi se è possibile installare una soluzione che utilizza Thread Local Storage.

1

Si sta effettuando una copia dei dati per ogni traccia e tutto funziona? quindi nessun problema

Ecco alcuni pensieri supplementari:

  • Se i dati vengono letti solo, è possibile condividere un singolo struct e tutto sarà ok, a patto che ogni lettura è piccolo e veloce (tipi base)
  • Se i dati devono essere scritti, ma "privati" (o contenuti) su ciascun thread, quindi inviare una copia a ciascun thread (cosa stai facendo). Avvertenza: presumo che i dati non siano troppo grandi e una copia non consumi molte risorse.
  • Se i dati devono essere scritti e i nuovi valori condivisi tra i thread, è necessario pensarci (leggere su di esso) e creare un progetto appropriato. Mi piace un oggetto transazionale per centralizzare ogni operazione di lettura/scrittura dei thread. Come un piccolo database in memoria. Controlla sul thread mutex, semafori e sezioni critiche). Gestire un enorme set di dati Ho usato un database per centralizzare le richieste (Vedi ODBM). È inoltre possibile controllare le librerie di accodamento di messaggistica esistenti (come MSMQ) per ordinare e sincronizzare le modifiche dei dati.

Spero che questo aiuti.

+0

Fortunatamente la struttura dei dati non sarà realmente condivisa tra i thread, diversi da quelli descritti sopra. Quindi se la struttura dei dati è contenuta all'interno di ogni thread (e ogni thread ha la sua struttura di dati OWN) non dovrebbe essere molto utile per i mutex. – Robb

0

Sembra improbabile che si desideri che ciascun thread funzioni sui dati e quindi almeno non occasionalmente un altro thread reagisce a ciò che un altro thread ha fatto al lavoro di un altro thread sui dati. Se sei veramente indipendente nel senso che nessun altro thread avrà mai veramente a cuore il lavoro che ha fatto un altro thread, allora ti suggerisco di fare una copia dei dati, altrimenti nel caso in cui tu voglia lavorare in un thread e fare quel risultato di quel lavoro disponibile su un altro thread ti suggerirei di passare un riferimento/puntatore all'oggetto intorno e quindi proteggere l'accesso ad esso tramite blocchi in modo che i thread possano lavorare con esso, in modo appropriato, suggerisco uno scrittore multi-read, single bloccare l'implementazione.

Problemi correlati