Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Per diversi giorni il Galaxy S26 Ultra di Samsung è stato il nostro compagno di vita. Oltre alle conferme del colosso coreano come la qualità del display e una suite AI senza rivali, arriva il Privacy Display, un unicum nel mondo smartphone. Ci sono ancora alcuni gap che non sono riusciti a colmare lato batteria e fotocamera, seppur con alcuni miglioramenti.
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Abbiamo provato per voi il nuovo DLC lanciato a sorpresa da Blizzard per Diablo II: Resurrected e quella che segue è una disamina dei nuovi contenuti che abbiamo avuto modo di sperimentare nel corso delle nostre sessioni di gioco, con particolare riguardo per la nuova classe dello Stregone
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Siamo tornati nel parco tecnologico di Trieste per il kick-off del programma che mette a disposizione di cinque startup le infrastrutture di ricerca, dal sincrotrone Elettra ai laboratori di genomica e HPC. Roberto Pillon racconta il modello e la visione
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-01-2009, 13:27   #1
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
[C++] QT threads - un'idea migliore ?

Avrei bisogno di qualche consiglio su un programma che sto facendo (C++ - Linux Ubuntu).

In pratica devo creare un record/playback client da inserire nel programma mumble che già usiamo per i nostri software di comunicazione.

In fase "record" il client deve registare l'audio e questo l'ho già fatto usando l'ottima libreria free "libsndfile".

In fase "playback" ho qualche problemino ... devo sincronizzare un thread "transport" ed uno "playback" in modo che quando quello "transport" riceve un comando (via tcp) tipo play, stop o set-position, quello "playback" esegua la giusta operazione.

Devo usare i threads di QT (QThread) perchè mumble li usa quindi mi ritrovo con 2 threads che hanno un metodo run() con un ciclo infinito.
Il thread "transport" controlla periodicamente se c'è un comando da eseguire e, se si, informa il thread "playback".

Non mi piace la soluzione che ho trovato ma è l'unica ... un QT mutex per ogni comando:
es: se arriva un comando stop, il thread "transport" locka il mutex stop e il thread "playback", quando prova a lockarlo, si ferma in attesa che venga sbloccato.
Non mi piace perchè ogni 1/4 di secondo i threads devono bloccare/sbloccare un mutex per ogni comando per non parlare poi del rischio deadlock visto il numero di mutex.

Qualcuno ha idee migliori ?
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z Mb - Win Eight SP (1 > yours) 16 Valve
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 14:22   #2
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Difficile da dire non conoscendo nei dettagli l'architettura. Ad esempio potresti usare una coda circolare in modo da fare il playback dei comandi solo tutti insieme (nota che inserimento in coda e prelievo lavorano su semafori diversi).
Serve comunque una mutex per l'inserimento perché ci possono essere più thread che tentano di incrementare il contatore.
C'è un solo thread che preleva, quindi di fatto non c'è bisogno di alcuna mutex ed il thread che preleva, se non ci sono dati da prelevare, può tornare a fare altro. Di fatto il thread che preleva non ha alcuna attesa. Quelli che scrivono attendono solo di prendere possesso della mutex in scrittura sul contatore oppure attendono in caso di coda piena.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 14:51   #3
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Quote:
Originariamente inviato da cionci Guarda i messaggi
Difficile da dire non conoscendo nei dettagli l'architettura. Ad esempio potresti usare una coda circolare in modo da fare il playback dei comandi solo tutti insieme (nota che inserimento in coda e prelievo lavorano su semafori diversi).
Serve comunque una mutex per l'inserimento perché ci possono essere più thread che tentano di incrementare il contatore.
C'è un solo thread che preleva, quindi di fatto non c'è bisogno di alcuna mutex ed il thread che preleva, se non ci sono dati da prelevare, può tornare a fare altro. Di fatto il thread che preleva non ha alcuna attesa. Quelli che scrivono attendono solo di prendere possesso della mutex in scrittura sul contatore oppure attendono in caso di coda piena.
Non ho capito molto
Che ci sia bisogno del mutex lo so ma non ho capito come fare per usarne solo uno ...
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 14:55   #4
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Forse ho capito ...

Potrei lockare una struttura con una variabile che indica l'azione da eseguire e una che indica il valore (per set-position, per esempio).

Se è "lockata per scrivere" dal thread transport, la leggo dal thread "playback" per sapere cosa deve fare.


Non so se è quello che intendi ma grazie dell'idea
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 15:13   #5
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da trallallero Guarda i messaggi
Non ho capito molto
Che ci sia bisogno del mutex lo so ma non ho capito come fare per usarne solo uno ...
Siamo d'accordo che ci siano N produttori e un consumatore ?
La coda circolare avrà M risorse.
Inizializzerai due QSemaphore vuote(M), piene(0), una mutex(unlocked) da condividere fra i produttori.
Un vettore:
Risorse buffer[M]:
int inserimento = 0;
int prelievo = 0;

Per l'inserimento:
1 - acquisisci vuote
2 - acquisisci la mutex
3 - buffer[inserimento] = miaRisorsa
4 - inserimento = (inserimento + 1) % M;
5 - release sulla mutex
6 - release su piene

Per il prelievo:
1 - tento l'acquisizione di piene, se fallisco ritorno al chiamante, non ci sono risorse disponibili
2 - se sono qui significa che ci sono risorse disponibili
3 - risorsaDaRitornare = buffer[prelievo];
4 - prelievo = (prelievo + 1) % M;
5 - release su vuote

Se noti prelievo e inserimento non si troveranno mai ad operare sullo stesso elemento di buffer, di conseguenza non c'è concorrenza su buffer. Non c'è concorrenza nemmeno sugli incrementi.
La concorrenza è solo fra inserimenti diversi (dato che non ci sono prelievi contemporanei) e viene gestita dalla mutex.

Questo è il classico esempio di coda circolare che è presente nella letteratura per la sincronizzazione fra processi
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 15:27   #6
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Mi sa che non fa per il caso mio ...
Io ho un singolo processo (che poi saranno 15 perchè avremo 15 playback clients) che ha solo 2 threads, uno capo, che decide cosa fare, ed uno "schiavo", che esegue.

Quindi ci deve essere concorrenza perchè se il capo decide che lo schiavo deve fermarsi, questo si deve fermare fino a cambio ordine.
Però è interssante questa coda circolare, ogni volta che intervieni tu ne imparo una nuova.


Quote:
Originariamente inviato da cionci Guarda i messaggi
Siamo d'accordo che ci siano N produttori e un consumatore ?
Ecco, mi sa che non siamo sincronizzati o non seguo il tuo linguaggio tecnico
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 15:43   #7
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
E' merito delle tue domande che sono sempre interessanti

Per produttore si intende colui che produce una risorsa (i comandi nel tuo caso), per consumatore si intende colui che consuma la risorsa (esegue i comandi).

Quindi hai un solo produttore e un solo consumatore, è ancora più semplice !!!
Inizializzerai due QSemaphore vuote(M), piene(0):

Comando buffer[M]:
int inserimento = 0;
int prelievo = 0;

Per l'inserimento:
1 - tento l'acquisizione di vuote, se fallisco ritorno al chiamante perché non ci sono risorse disponibili
2 - buffer[inserimento] = mioComando
3 - inserimento = (inserimento + 1) % M;
4 - release su piene

Per il prelievo:
1 - acquisisco piene (mi sembra di capire che se non ci sono comandi il consumatore si debba fermare)
2 - comandoDaEseguire = buffer[prelievo];
3 - prelievo = (prelievo + 1) % M;
4 - release su vuote
5 - ritorno comandoDaEseguire al chiamante

Credo che questa cosa sia perfetta per te. In realtà ci sono due mutex, ma sono nascoste nei due semafori, però solo un processo si può bloccare su ogni mutex e non succede mai in contemporanea.
Di fatto quando il consumatore ha finito i comandi si blocca autonomamente sul semaforo fino a quando il produttore non inserirà un nuovo comando.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 15:56   #8
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Scusa ma non ho capito questo
Quote:
Originariamente inviato da cionci
3 - inserimento = (inserimento + 1) % M;
...
3 - prelievo = (prelievo + 1) % M;
perchè % M ?
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 16:18   #9
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da trallallero Guarda i messaggi
Scusa ma non ho capito questo


perchè % M ?
E' l'operatore di modulo o resto della divisione intera. M è il numero di risorse. Se il contatore raggiunge il valore M il modulo a M torna zero e quindi permette di rendere la coda circolare
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 16:21   #10
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Considera il semaforo come un contatore, ogni volta che rilasci il semaforo lo incrementi, ogni volta che lo acquisisci lo decrementi, se il contatore è zero e tento di fare un'acquisizione il mio thread si blocca in attesa che torni maggiore di zero.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 16:25   #11
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Quote:
Originariamente inviato da cionci Guarda i messaggi
E' l'operatore di modulo o resto della divisione intera. M è il numero di risorse. Se il contatore raggiunge il valore M il modulo a M torna zero e quindi permette di rendere la coda circolare
Geniale

sapevo che è il resto della divisione ma non riuscivo a capire la sua utilità!

Quote:
Originariamente inviato da cionci Guarda i messaggi
Considera il semaforo come un contatore, ogni volta che rilasci il semaforo lo incrementi, ogni volta che lo acquisisci lo decrementi, se il contatore è zero e tento di fare un'acquisizione il mio thread si blocca in attesa che torni maggiore di zero.
Adesso vado a casa, sto fuso perchè sto anche combattendo con un portatile nuovo, cercando di installare winxp
Domani a mente fresca riguardo il tutto.

Grazie mille
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 26-01-2009, 16:27   #12
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Non ti preoccupare, il meccanismo è fine, ma è semplice
Per una miglior comprensione sostituisci la release con nomeSemaforo++ e l'acquisizione con nomeSemaforo-- (tieni conto che non può mai arrivare sotto zero). Ovviamente solo per fare i conti su carta

Ultima modifica di cionci : 26-01-2009 alle 16:30.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 09:58   #13
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Ok, sono lucido e riposato

Mi sa che c'è qualcosa di troppo nella tua soluzione ...

Non è che "se non ci sono comandi il consumatore si deve fermare" ma dipende dall'ultimo comando ottenuto.
Immagina un cd player: premi "play" e il cd parte; fino a che non riceve un altro comando (o non finisce il cd) il cd viene riprodotto.
Poi viene premuto "pause", nuovo comando, e il cd si ferma - fino ad un nuovo comando il cd sta fermo.
etc etc.

Quindi non capisco l'utilità della coda circolare.

Probabilmente mi basta un mutex che blocca una variabile "comando"
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 11:14   #14
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Tu hai chiesto una soluzione per evitare che i due thread si sincronizzassero. Questa è una soluzione. Ad evitare che il consumatore si blocchi ci vuole poco (tryAcquire al posto di acquire).

Spiegami qualcosa di più sui comandi. Se il thread produttore produce molti comandi. E possibile che ci siano più comandi in attesa di essere eseguiti ? Se la risposta è sì, allora ti serve ad ogni costo una coda circolare. A meno che non voglia far bloccare il tuo produttore su una mutex fino a quando il consumatore non ha consumato il comando

Io la vedo così. Quello che mi immagino è che il produttore possa produrre molti comandi e che il consumatore debba fare "qualcosa" con questi comandi, questo "qualcosa" occupa tempo e quindi non rende il consumatore reattivo al massimo ai comandi. Il produttore non si può permettere di fermarsi ad aspettare che il consumatore esegua il comando, ma nemmeno il consumatore (visto che dovrai fare un playback dovrai rispettare temporizzazioni strette). Per garantirti la massima reattività ai comandi:
Nuova architettura.
Thread A: produttore
Thread B: consumatore
Thread C: playback
Coda come sopra: bloccante per il consumatore e non bloccante per il produttore (la coda non si dovrebbe riempire mai, tranne per errori, quindi bene o male se la tryAcquire fallisce dovresti generare un'eccezione).

Con questa architettura è palese che quando non ci sono comandi il consumatore resta sempre in attesa sul semaforo del prelievo. Quindi il consumo di uno comando è veramente istantaneo.
Il produttore ha attesa zero sulla coda perché è praticamente sempre vuota. All'inserimento di un comando il consumatore viene risvegliato e preleva immediatamente il comando. All'uscita dal prelievo lo esegue su playback: se deve stoppare il playback acquisirà una mutex, se deve avviare il playback rilascerà la stessa mutex, se deve fare altre cose lo saprai te cosa deve fare
Il consumatore non appena ha eseguito il comando si rimette in attesa sul prelievo fino a quando non riceve un altro comando.

L'interfaccia migliore fra consumatore e playback al di là di come te la ho descritta sopra dovrebbe essere questa:

consumatore:
prelevo comando dalla coda
acquisisco MutexM
setto il comando
se è il comando stop acquisisco MutexStop
se è il comando play rilascio MutexStop
rilascio MutexM

playback:
acquisisco MutexM
se non ci sono comandi continuo ad eseguire quello attuale, salto al rilascio
recupero il comando
se è il comando di stop, rilascio MutexM, acquisisco MutexStop (qui si ferma), acquisisco MutexM, comando = Play
rilascio MutexM
eseguo il comando che mi è stato impartito

Alla fine: se per il tuo produttore è accettabile l'attesa fra l'acquisizione ed il rilascio di MutexM allora puoi tranquillamente sostituire il produttore al consumatore mantenendo un'architettura a 2 thread.

Ultima modifica di cionci : 27-01-2009 alle 11:19.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 11:32   #15
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Mamma mia, come al solito mi hai dato parecchi input

Adesso provo un pò e poi vedo quale soluzione prendere (sicuramente ho già abbandonato l'orribile idea di un mutex per ogni comando, grazie).

Diciamo che l'attesa tra l'acquisizione ed il rilascio è accettabilissima (anche perchè ho carta bianca quindi decido io ).
Prima facevo un blocco mutex e lettura da file ogni secondo ma poi sono arrivato ad 1/4 di secondo. Quindi dal momento in cui premo stop a quello in cui il playback si ferma passano 2.5 decimi di secondo, direi che è impercettibile.

Quote:
Originariamente inviato da cionci
Spiegami qualcosa di più sui comandi. Se il thread produttore produce molti comandi. E possibile che ci siano più comandi in attesa di essere eseguiti ? Se la risposta è sì, allora ti serve ad ogni costo una coda circolare. A meno che non voglia far bloccare il tuo produttore su una mutex fino a quando il consumatore non ha consumato il comando
Ecco, una cosa che dovrei prevedere è il militare che si mette a premere i tastini play/stop/setpos all'impazzata. Altrimenti non ci dobvrebbe essere una coda di comandi. Controllo ogni 1/4 di secondo, mica può essere così veloce un umano (militare poi )


PS: Ieri sera (come tutte le sere) suonavo la mia chitarra elettrica ed ho fatto caso al Cubase (programma professionale): quando premi start e stop c'è sempre un periodo piuttosto lungo di attesa; sullo start è ovvio perché ogni instrumento ha la sua latency, ma sullo stop immagino sia per lo stesso mio motivo (ovvero "attesa tra l'acquisizione ed il rilascio"). Quindi ho pensato: se lo fa una grossa società come la Steinberg lo posso fare anche io
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 11:42   #16
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Ok, allora vai di metodo a 2 thread.
E' importante la sequenza di acquisizione e rilascio delle mutex
Evita deadlock Viene chiamato "cambio del testimone".
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 11:50   #17
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Comuqnue io verificherei cosa avviene se vengono premuti due tasti contemporaneamente, probabilmente in questo modo rimani un po' indietro, mi spiego:
- tempo 0: premo play e stop (lo stop leggermente dopo)
- tempo 250ms: premo play e stop (lo stop leggermente dopo)
- tempo 500ms: premo tasto "Guerra termonucleare globale"

Il programma dovrebbe reagire in questo modo:
- tempo 20ms: leggo play
- tempo 270ms: leggo stop
- tempo 520ms: leggo play
- tempo 1020ms: leggo stop
- tempo 1270ms: leggo "Guerra termonucleare globale"

Ho ritardato di 3/4 di secondo la fine del mondo
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 12:19   #18
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
Quote:
Originariamente inviato da cionci Guarda i messaggi
Ok, allora vai di metodo a 2 thread.
E' importante la sequenza di acquisizione e rilascio delle mutex
Evita deadlock Viene chiamato "cambio del testimone".
Veramente mi ritrovo con 3 threads ma mi sa che ne posso eliminare uno (a furia di testare mi perdo ...)

Codice:
class RingBuffer 
class WavReader : public RingBuffer, QThread
class WavTransport : public QThread
class WavPlayer : public QThread
Quote:
Originariamente inviato da cionci Guarda i messaggi
Comuqnue io verificherei cosa avviene se vengono premuti due tasti contemporaneamente, probabilmente in questo modo rimani un po' indietro, mi spiego:
- tempo 0: premo play e stop (lo stop leggermente dopo)
- tempo 250ms: premo play e stop (lo stop leggermente dopo)
- tempo 500ms: premo tasto "Guerra termonucleare globale"

Il programma dovrebbe reagire in questo modo:
- tempo 20ms: leggo play
- tempo 270ms: leggo stop
- tempo 520ms: leggo play
- tempo 1020ms: leggo stop
- tempo 1270ms: leggo "Guerra termonucleare globale"
Il tempo di risposta quando premo stop non è 1/4 di secondo ma di 1 secondo e non capisco perchè (forse è il mutex nella classe RingBuffer, devo controllare cosa ho fatto)

Quote:
Originariamente inviato da cionci Guarda i messaggi
Ho ritardato di 3/4 di secondo la fine del mondo
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 12:36   #19
trallallero
Senior Member
 
L'Avatar di trallallero
 
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
visto che ci siamo faccio un'altra domanda:

15 playback clients che riproducono 15 diversi audio file, sono perfettamente sincronizzati ?
non intendo l'audio in se ma proprio i tempi di esecuzione dei threads dei 15 processi.
trallallero è offline   Rispondi citando il messaggio o parte di esso
Old 27-01-2009, 16:03   #20
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Sopra era "passaggio del testimone"
Quote:
Originariamente inviato da trallallero Guarda i messaggi
15 playback clients che riproducono 15 diversi audio file, sono perfettamente sincronizzati ?
non intendo l'audio in se ma proprio i tempi di esecuzione dei threads dei 15 processi.
Credo proprio che non ci sia garanzia che avanzino in maniera sincronizzata. 15 sono tanti. In tal caso ti conviene sincronizzarli.

Puoi usare una QWaitCondition.

Codice:
mutex.lock();
numberOfThreadInside++;
if(numberOfThreadInside < 15)
{
    allThreadInside.wait(&mutex);
}
else
{
   allThreadInside.wakeAll();
}
numberOfThreadInside--;
mutex.unlock();
In ogni casi bisogna vedere che siano mantenuti i requisiti temporali.

Ultima modifica di cionci : 27-01-2009 alle 16:14.
cionci è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo Recensione Samsung Galaxy S26 Ultra: finalmente ...
Diablo II Resurrected: il nuovo DLC Reign of the Warlock Diablo II Resurrected: il nuovo DLC Reign of the...
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup Deep Tech Revolution: così Area Science P...
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo HP OMEN MAX 16 con RTX 5080: potenza da desktop ...
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta Recensione Google Pixel 10a, si migliora poco ma...
Le analisi di ALMA sulla cometa interste...
La missione cinese Tianwen-3 per portare...
Un satellite di HEO Space ha catturato u...
Mini LED 144Hz a prezzo folle: questo Hi...
Novità per Fortinet: arrivano For...
Volkswagen e Xpeng, il SUV è real...
Volkswagen ribattezza ID.3 e le dà un mo...
Aruba rende disponibile VMware Hosted Pr...
Questa Olympus da 20 MP con stabilizzazi...
Il nuovo dispositivo di Rabbit si chiama...
'Se avete RAM, siamo pronti ad acquistar...
Veeam corregge diverse vulnerabilit&agra...
MacBook Neo segna una svolta per Apple: ...
Polestar pubblica il report LCA di Poles...
Il rame non basta più: NVIDIA, AM...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 22:33.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v