View Full Version : [c]MULTI-THREADS: multi esperti a me!
trallallero
26-04-2007, 12:46
Avrei un problemino con un modulo che logga msg ed errori di un intero progetto.
Questo progetto ha parecchi threads (e io non sono esperto in 3ds) che potrebbero scrivere contemporaneamente i log quindi chiamare nello stesso istante il modulo log.
Ci sono problemi ? il S.O. ci pensa da solo o devo fare un ulteriore thread che faccia da interfaccia al loggatore ?
grassie :)
Avrei un problemino con un modulo che logga msg ed errori di un intero progetto.
Questo progetto ha parecchi threads (e io non sono esperto in 3ds) che potrebbero scrivere contemporaneamente i log quindi chiamare nello stesso istante il modulo log.
Ci sono problemi ? il S.O. ci pensa da solo o devo fare un ulteriore thread che faccia da interfaccia al loggatore ?
grassie :)
no non puoi avere problemi... inoltre i thread non scrivono in contemporanea.
Sono appunto thread quindi uno alla volta con le loro precedenze di privilegio.
Sempre uno alla volta non possono scrivere in contemporanea indipendemente dall'OS.
beppegrillo
26-04-2007, 12:58
Avrei un problemino con un modulo che logga msg ed errori di un intero progetto.
Questo progetto ha parecchi threads (e io non sono esperto in 3ds) che potrebbero scrivere contemporaneamente i log quindi chiamare nello stesso istante il modulo log.
Ci sono problemi ? il S.O. ci pensa da solo o devo fare un ulteriore thread che faccia da interfaccia al loggatore ?
grassie :)
Stai chiedendo se più thread scrivono sullo stesso file, puoi lasciarlo così oppure devi gestirlo tu?
Non vorrei sbagliarlo, ma prendilo come hint, che io sappia puoi infischiartene solo se questi thread leggono il file, mentre se scrivono devi usare meccanismi di mutex.
Vedi un po se questo può esserti d'aiuto. http://en.wikipedia.org/wiki/File_locking
beppegrillo
26-04-2007, 12:59
no non puoi avere problemi... inoltre i thread non scrivono in contemporanea.
Sono appunto thread quindi uno alla volta con le loro precedenze di privilegio.
Sempre uno alla volta non possono scrivere in contemporanea indipendemente dall'OS.
Beh non è mica detto scusa, metti che thread 1 stà scrivendo sul file, viene prelazionato da thread 2 e inizia a scrivere sullo stesso file, hai un incosistenza no?
Mica la scrittura su file è una operazione atomica?
trallallero
26-04-2007, 13:02
no non puoi avere problemi... inoltre i thread non scrivono in contemporanea.
Sono appunto thread quindi uno alla volta con le loro precedenze di privilegio.
Sempre uno alla volta non possono scrivere in contemporanea indipendemente dall'OS.
sicuro ? a chiedermelo e´ stato proprio quello che ha "designato" i 3ds e li sta implementando. Quindi immagno si esperto di 3ds ...
Io poi, per motivi di spazio, zippo tutti i log creati eliminando quelli vecchi ma per non appesantire il tutto chiamo in parallelo con una fork il processo zip.
Sicuro che posso star tranquillo ?
trallallero
26-04-2007, 13:04
Beh non è mica detto scusa, metti che thread 1 stà scrivendo sul file, viene prelazionato da thread 2 e inizia a scrivere sullo stesso file, hai un incosistenza no?
infatti mi sembra strano, mi piacerebbe testare ma non so creare i 3ds :stordita:
Mica la scrittura su file è una operazione atomica?
speriamo di no ... sono contro il nucleare :O
trallallero
26-04-2007, 13:11
che poi il mio modulo non e´ un processo a parte ma un .o che verra´ linkato a svariati eseguibili che a loto volta creeranno svariati 3ds ...
tomminno
26-04-2007, 14:03
Per il log non puoi realizzare una coda di messaggi da scrivere in cui tutti i thread vanno ad accodare le loro richieste così che questa venga svuotata su un thread separato?
Non avresti più problemi di concorrenza in scrittura su file, ma solo di gestione della struttura che userai per la coda.
Così facendo hai in più il vantaggio che i thread non vengono "rallentati" dal processo di scrittura su file.
trallallero
26-04-2007, 14:21
Per il log non puoi realizzare una coda di messaggi da scrivere in cui tutti i thread vanno ad accodare le loro richieste così che questa venga svuotata su un thread separato?
Non avresti più problemi di concorrenza in scrittura su file, ma solo di gestione della struttura che userai per la coda.
Così facendo hai in più il vantaggio che i thread non vengono "rallentati" dal processo di scrittura su file.
e´ quello che vorrebbe evitare il crucco qui. Non so bene perche´ (son qui da poco piu´di 1 settimana) ma penso che sia perche´ abbiamo decine di 3d aperti contemporaneamente.
Grazie comunque ;)
trallallero
26-04-2007, 14:34
Stai chiedendo se più thread scrivono sullo stesso file, puoi lasciarlo così oppure devi gestirlo tu?
Non vorrei sbagliarlo, ma prendilo come hint, che io sappia puoi infischiartene solo se questi thread leggono il file, mentre se scrivono devi usare meccanismi di mutex.
Vedi un po se questo può esserti d'aiuto. http://en.wikipedia.org/wiki/File_locking
infatti ho provato a creare 5 threads (grazie ad uno stupido esempio in rete) e scrive veramente alla caxxo :nono:
grazie do un´occhiata.
Mi e´ appena venuto il crucco a dire che forse con il flag O_SYNC al file si risolve ...
beppegrillo
26-04-2007, 14:49
infatti ho provato a creare 5 threads (grazie ad uno stupido esempio in rete) e scrive veramente alla caxxo :nono:
grazie do un´occhiata.
Mi e´ appena venuto il crucco a dire che forse con il flag O_SYNC al file si risolve ...
O_SYNC
Write I/O operations on the file descriptor complete as defined by synchronised I/O file integrity completion.
Boh prova, sicuramente fai molto prima così, che ad esempio una cosa simile:
pthread_mutex_lock(mutex_scrittura)
fd = open(file,"rw");
write(fd,'blah',..)
close(fd)
pthread_mutex_unlock(mutex_scrittura)
trallallero
26-04-2007, 14:52
mentre se scrivono devi usare meccanismi di mutex.
se ho capito bene il lock rallenta il tutto perche´ ogni chiamante aspetta il turno suo. Ovvero perdita di prestazioni. Purtroppo penso che non sia la soluzione giusta in questo progetto.
Per il log non puoi realizzare una coda di messaggi da scrivere in cui tutti i thread vanno ad accodare le loro richieste così che questa venga svuotata su un thread separato?
Non avresti più problemi di concorrenza in scrittura su file, ma solo di gestione della struttura che userai per la coda.
Così facendo hai in più il vantaggio che i thread non vengono "rallentati" dal processo di scrittura su file.
si mi sa che e´ l´unica strada ... hai qualche esempio ?
trallallero
26-04-2007, 14:53
O_SYNC
Write I/O operations on the file descriptor complete as defined by synchronised I/O file integrity completion.
Boh prova, sicuramente fai molto prima così, che ad esempio una cosa simile:
pthread_mutex_lock(mutex_scrittura)
fd = open(file,"rw");
write(fd,'blah',..)
close(fd)
pthread_mutex_unlock(mutex_scrittura)
mizzeca! non basta la write in mutex ? ogni scrittura deve essere un´apertura chiusura ?
trallallero
26-04-2007, 15:18
correggetemi se sbaglio per favore:
ho messo un
pthread_mutex_lock(&mutex);
...
fprintf(...);
...
pthread_mutex_unlock(&mutex);
e va tutto a meraviglia.
Ma e´ piu´ lento o no ? :help:
beppegrillo
26-04-2007, 15:22
correggetemi se sbaglio per favore:
ho messo un
pthread_mutex_lock(&mutex);
...
fprintf(...);
...
pthread_mutex_unlock(&mutex);
e va tutto a meraviglia.
Ma e´ piu´ lento o no ? :help:
Beh si, puoi ad esempio scrivere su un buffer come ti ha suggerito qualcuno.
Però a stò punto devi vedere quanto ti conviene, perchè col buffer hai alcuni svantaggi :
1)nuove strutture dati
2)overhead dovuto al processo thread che deve svuotarlo nel file
3)e credo che anche quando aggiungi roba al buffer, devi usare la mutua esclusione
In poche parole, dipende un po da quanti thread hai e da quanto lavorano.
trallallero
26-04-2007, 15:27
Beh si, puoi ad esempio scrivere su un buffer come ti ha suggerito qualcuno.
Però a stò punto devi vedere quanto ti conviene, perchè col buffer hai alcuni svantaggi :
1)nuove strutture dati
2)overhead dovuto al processo thread che deve svuotarlo nel file
3)e credo che anche quando aggiungi roba al buffer, devi usare la mutua esclusione
In poche parole, dipende un po da quanti thread hai e da quanto lavorano.
beh, questa soluzione (mutex) e´ stata accetta dal krukken per adesso. Ha detto che ha trovato altri punti deboli nei 3ds quindi prima risolvera´ quelli poi se ne riparla.
Grazie a tutti :)
Voto per la soluzione di Tommino. Sincronizzando sull'operazione di scrittura (lock - print - lock) ognuno dei Thread che vuole inviare un messaggio di log deve attendere per il tempo necessario a scrivere i dati. Se i dati finiscono su un disco fisso l'attesa può essere rilevante.
Se usi una coda concorrente con un Thread che la svuota, ogni Thread deve attendere per il tempo necessario a copiare il messaggio o un puntatore al messaggio da una fetta di RAM ad un'altra.
Poichè idealmente la rapidità di stoccaggio dei messaggi nella coda è più elevata della velocità di scrittura degli stessi (cioè il rubinetto è molto grande e lo scarico molto piccolo) devi anche introdurre un blocco euristico sull'accodamento dei messaggi. Del genere se il totale dei messaggi passa i dieci megabyte l'accodamento viene bloccato finchè le dimensioni della coda non tornino sotto ad un certo livello di guardia.
Nota che il sistema ti consente di ottimizzare le operazioni di scrittura facendo in modo che essa avvenga non ad ogni messaggio ma, ad esempio, al raggiungimento di un numero di byte ottimale per la scrittura. Ad esempio si potrebbe pensare di scrivere i dati a blocchi di dimensioni pari ad un multiplo della dimensione di un cluster.
trallallero
26-04-2007, 15:50
Voto per la soluzione di Tommino. Sincronizzando sull'operazione di scrittura (lock - print - lock) ognuno dei Thread che vuole inviare un messaggio di log deve attendere per il tempo necessario a scrivere i dati. Se i dati finiscono su un disco fisso l'attesa può essere rilevante.
Se usi una coda concorrente con un Thread che la svuota, ogni Thread deve attendere per il tempo necessario a copiare il messaggio o un puntatore al messaggio da una fetta di RAM ad un'altra.
Poichè idealmente la rapidità di stoccaggio dei messaggi nella coda è più elevata della velocità di scrittura degli stessi (cioè il rubinetto è molto grande e lo scarico molto piccolo) devi anche introdurre un blocco euristico sull'accodamento dei messaggi. Del genere se il totale dei messaggi passa i dieci megabyte l'accodamento viene bloccato finchè le dimensioni della coda non tornino sotto ad un certo livello di guardia.
Nota che il sistema ti consente di ottimizzare le operazioni di scrittura facendo in modo che essa avvenga non ad ogni messaggio ma, ad esempio, al raggiungimento di un numero di byte ottimale per la scrittura. Ad esempio si potrebbe pensare di scrivere i dati a blocchi di dimensioni pari ad un multiplo della dimensione di un cluster.
interessante ma la scrittura a blocchi non puo´ andare perche´ ho creato un sistema con una lista circolare che memorizza n nomi di files e cancella sempre l´ultimo piu´ vecchio e zippa quelli che chiude. Quindi ne crea uno quando raggiunge una tot size, ma a blocchi significherebbe avere dei messaggi spezzati ... non so se puo´andare.
E poi per avere sempre i log aggiornati faccio una fflush ad ogni scrittura. Lo so che rallenta ma se crasha vogliamo sapere perche´.
La coda pero´ mi piace come idea ...
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.