Torna indietro   Hardware Upgrade Forum > Software > Programmazione

DJI Mavic 4 Pro: sblocca un nuovo livello per le riprese aeree
DJI Mavic 4 Pro: sblocca un nuovo livello per le riprese aeree
DJI Mavic 4 Pro porta in dote il nuovo Stabilizzatore Infinity a 360°, che permette nuovi gradi di libertà nelle riprese aeree. Non solo può ruotare a 360 gradi, ma abilita anche riprese dal basso, con inclinazione della videocamera fino a 70°. Il triplo modulo di ripresa offre una fotocamera Hasselblad 28mm con sensore da 100 megapixel e video 6K, ma si spinge fino al teleobiettivo da 50 megapixel e 168mm di focale equivalente. Nuova avionica e batteria per voli fino a 51 minuti di autonomia. La nostra prova
Idrogeno verde in Europa: nuovi studi prevedono costi ben superiori alle aspettative
Idrogeno verde in Europa: nuovi studi prevedono costi ben superiori alle aspettative
Siamo tutti d'accordo: una eventuale diffusione massiccia di idrogeno verde, prodotto esclusivamente da fonti rinnovabili, risolverebbe tanti problemi. Ma siamo ancora lontanissimi da uno scenario del genere e c'entra anche l'Africa. Facciamo il punto della situazione sulla base di studi autorevoli, recentemente pubblicati.
Mario Kart World lancia Switch 2: la magia Nintendo ora in 4K
Mario Kart World lancia Switch 2: la magia Nintendo ora in 4K
Abbiamo provato esaustivamente due dei titoli di lancio della nuova console di Nintendo, il cui debutto è previsto per la settimana in corso. Mario Kart World e Nintendo Switch 2 Welcome Tour si rivelano sorprendenti per certi aspetti e anche perché esaltano alcune delle nuove caratteristiche di Switch 2
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-04-2011, 19:37   #1
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
[C/C++] problemi coi thread

ciao,
ho due thread che ho chiamato come di consueto PRODUTTORE e CONSUMATORE.

Il produttore popola una array mentre come viene ovvio pensare CONSUMATORE lo usa.

Ho settato una variabile semaforica in modo che il CONSUMATORE non può accedere all'array sino a quando questo non è aggiornato completamente e da qui il problema: come faccio a fare in modo che l'aggiornamento non avvenga a CPU time ma ad esempio ogni 50 ms mentre il consumatore fa la sua parte ogni 250 ms ?

Essendoci in mezzo il semaforo se ritardo il produttore di conseguenza ritardo anche il consumatore ma desidererei tenere separati i due thread in modo che i rispettivi "lavori" avvengano in tempi differenti per mantenendo i vincoli dell'accesso all'array da parte del consumatore.

grazie
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 20:56   #2
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
edit

Ultima modifica di misterx : 13-04-2011 alle 05:47.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 13:46   #3
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Risposta banale (spero di non suggerirti cavolate): fai eseguire a entrambi i thread (quando non hanno il lock sull'array ovviamente) una sleep; prodottore dormirà 50ms, consumatore dormirà 250ms.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 15:06   #4
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
Quote:
Originariamente inviato da banryu79 Guarda i messaggi
Risposta banale (spero di non suggerirti cavolate): fai eseguire a entrambi i thread (quando non hanno il lock sull'array ovviamente) una sleep; prodottore dormirà 50ms, consumatore dormirà 250ms.
ho provato questa strada ma mi sonon accorto che i due thread attendenndo reciprocamente il semaforo verde, sono soggetti entrambi al tempo più lungo.
Magari è la mia implementazione ad essere bacata.

Codice:
semaforo=0;
thread_1
{
         if(semaforo==0)
         {
                popola array;
        }
        semaforo=1;
}

thread_2
{
         if(semaforo==1)
         {
                consumaa array;
        }
        semaforo=0;
}
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 15:10   #5
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da misterx Guarda i messaggi
ciao,
ho due thread che ho chiamato come di consueto PRODUTTORE e CONSUMATORE.

Il produttore popola una array mentre come viene ovvio pensare CONSUMATORE lo usa.

Ho settato una variabile semaforica in modo che il CONSUMATORE non può accedere all'array sino a quando questo non è aggiornato completamente e da qui il problema: come faccio a fare in modo che l'aggiornamento non avvenga a CPU time ma ad esempio ogni 50 ms mentre il consumatore fa la sua parte ogni 250 ms ?

Essendoci in mezzo il semaforo se ritardo il produttore di conseguenza ritardo anche il consumatore ma desidererei tenere separati i due thread in modo che i rispettivi "lavori" avvengano in tempi differenti per mantenendo i vincoli dell'accesso all'array da parte del consumatore.

grazie
Il produttore gira a frequenza quadrupla rispetto il consumatore: va bene che il produttore acceda solo alla versione piu' recente, e "perda" le tre precedenti ? O deve poter accedere anche alle elaborazioni intermedie ?

Nell'ipotesi che sia vera la prima affermazione, e' relativamente semplice:
devi avere due scheduler distinti nel primo e secondo thread. Uno impostato a 250ms e l'altro a 50ms. Se il tuo ambiente non te fornisce si puo' crearne uno a base di (sotto unix) clock_gettime e clock_nanosleep (o le equivalenti sotto windows). Devi solo tenere presente che non puoi fare semplicemente una sleep di 50ms, ma devi tenere conto di quanto dura il singolo loop
Fatto questo, non devi far altro che fare una cosa come la seguente:


Codice:
// producer
scheduler sched(50000); // usec
while(!done)
{
    do_something();
    lock_array();
    perform_changes();
    unlock_array();
    sched.wait_next();
}

// consumer
scheduler sched(250000); // usec
while(!done)
{
    lock_array();
    read_changes();
    unlock_array();
    do_something_else();
    sched.wait_next();
}
Tieni presente che idealmente devi solo copiare i dati necessari da/verso l'array, mentre lo blocchi. Non vuoi che il produttore aspetti 250ms frattanto che il consumatore fa i cavoli suoi bloccandoti l'array.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 15:12   #6
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da misterx Guarda i messaggi
ho provato questa strada ma mi sonon accorto che i due thread attendenndo reciprocamente il semaforo verde, sono soggetti entrambi al tempo più lungo.
Magari è la mia implementazione ad essere bacata.

Codice:
semaforo=0;
thread_1
{
         if(semaforo==0)
         {
                popola array;
        }
        semaforo=1;
}

thread_2
{
         if(semaforo==1)
         {
                consumaa array;
        }
        semaforo=0;
}
Come dicevo sopra devi tenere bloccato l'array per il tempo minimo per copiare i dati. Meglio ancora, invece di usare un semafoto usa qualcosa di piu' alto livello tipo una coda di messaggi, e ottieni questo quasi automaticamente (ed il codice e' piu' pulito).
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 15:35   #7
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
grazie marco.r

quello che interessa a me è avere sempre l'array aggiornato ma impedire che il consumatore vi acceda se non è stato completamente aggiornato.

Il semaforo risponde allo scopo ma i due thread viaggiano sincroni anzi, il più lento "rallenta" quello più veloce.

Sto sviluppando in Borland Builder C++
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 15:45   #8
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da misterx Guarda i messaggi
grazie marco.r

quello che interessa a me è avere sempre l'array aggiornato ma impedire che il consumatore vi acceda se non è stato completamente aggiornato.

Il semaforo risponde allo scopo ma i due thread viaggiano sincroni anzi, il più lento "rallenta" quello più veloce.

Sto sviluppando in Borland Builder C++
Perche' per come usi tu il semaforo, il produttore aspetta che il consumatore abbia eseguito il suo loop.
Come ti suggerisco io invece, con u nsemplice lock, il produttore puo' bloccare/sbloccare l'accesso all'array quante volte vuole, ma essendo sincronizzato, cmq produttore e consumatore non possono accedervi contemporaneamente
per usare la tua notazione, dovresti usare qualcosa tipo
Codice:
semaforo=0;
thread_1
{
    popola_array();
    sem_post(semaforo);
    while( ... )
    {
        aspetta prossimi 50ms
        sem_wait(semaforo);
        popola array;
        sem_post(semaforo);
    }
}

thread_2
{
    while( ... )
   {
        aspetta prossimi 250ms
        sem_wait(semaforo);
        consumaa array;
        sem_post(semaforo);
    }
}
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele

Ultima modifica di marco.r : 13-04-2011 alle 15:48.
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 18:25   #9
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Perche' per come usi tu il semaforo, il produttore aspetta che il consumatore abbia eseguito il suo loop.
Come ti suggerisco io invece, con u nsemplice lock, il produttore puo' bloccare/sbloccare l'accesso all'array quante volte vuole, ma essendo sincronizzato, cmq produttore e consumatore non possono accedervi contemporaneamente
per usare la tua notazione, dovresti usare qualcosa tipo
Codice:
semaforo=0;
thread_1
{
    popola_array();
    sem_post(semaforo);
    while( ... )
    {
        aspetta prossimi 50ms
        sem_wait(semaforo);
        popola array;
        sem_post(semaforo);
    }
}

thread_2
{
    while( ... )
   {
        aspetta prossimi 250ms
        sem_wait(semaforo);
        consumaa array;
        sem_post(semaforo);
    }
}
non mi è chiara la tua implementazione di sem_wait(semaforo); e sem_post(semaforo);

Codice:
int array[100];

thread_1
{
       while(1)
       {
          Sleep(50);
          for(i=0; i<100; i++)
          array[i]=rand();
        }
}

thread_2
{
       while(1)
       {
          Sleep(250);
          for(i=0; i<100; i++)
          printf("%d\n",array[i]);
        }
}
una cosa di questo tipo credo sia fuori controllo in quanto non saprei quando verranno eseguiti i due thread
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 19:19   #10
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
ora ho capito cosa intendevi, così funziona molto bene
Codice:
int array[100];

thread_1
{
       while(1)
       {
          sem=0;          
          for(i=0; i<100; i++)
          array[i]=rand();
          sem=1;
          Sleep(50);
        }
}

thread_2
{
       while(1)
       {
          if(sem==1)
          {
          for(i=0; i<100; i++)
          printf("%d\n",array[i]);
        }
         Sleep(250);
        }
}

Ultima modifica di misterx : 13-04-2011 alle 19:22.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 20:38   #11
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Non puoi usare una semplice variabile per la sincronizzazione. Innanzi tutto non puoi garantire che l atray venga copiato ogni 250 ms. Perché invece di attendere che venga finita la scrittura dal produce, aspetti la volta dopo. Potenzialmente se hai sfoga la copia non avviene mai. Peggio ancora eventuali ottizzazioni del compilatore possono causare problemi di sincronizzazione del valore del semaforo tra due thread.
Invece che un intero usa un semaforo vero e proprio o più precisamente un mutex. Li trovi tra le api di windows
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 13-04-2011, 21:14   #12
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
ed haai ragione. Funzionava meglio la prima implementazione mentre questa seconda potrebbe avvenire che il produttore porta a termine sempre il suo compito ma quando termina e parte il consumatore, se il thread consumatore finisce il suo quantum di tempo a disposizione, si torna al produttore che inibisce il funzionamento del consumatore

non ho mai usato i mutex
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 07:18   #13
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
ciao,
non sono molto convinto di come sto usando i mutex


Codice:
int array[100];

/* PRODUTTORE */

hMutex=CreateMutex(NULL, FALSE,NULL);
while(.....)
{
               WaitForSingleObject(hMutex,INFINITE);

               for(int i=0; i<100; i++)
               array[i]=rand();

               ReleaseMutex(hMutex);
              Sleep(50);

}


/* CONSUMATORE */

hMutex=CreateMutex(NULL, FALSE,NULL);
while(.....)
{
               WaitForSingleObject(hMutex,INFINITE);

               for(int i=0; i<100; i++)
               printf(%d\n,array[i]);

               ReleaseMutex(hMutex);
              Sleep(250);

}

funziona a questo modo ?
Come lo verifico ?

grazie 1000
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 08:15   #14
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da misterx Guarda i messaggi
ciao,
non sono molto convinto di come sto usando i mutex
Devi usare lo stesso mutex, oppure crearlo "named"(non ho idea di come si faccia sotto windows) usando lo stesso nome in entrambi i thread.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 08:22   #15
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
ma va creato un mutex globale allora ?

Oppure si crea un mutex PRODUTTORE e lo si usa in consumatore e viceversa?

Non mi è chiaro il meccanismo
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 08:33   #16
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Ti serve un unico mutex. Concettualmente e'come la variabile intera che usavi tu, solo che e' implementata opportunamente.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 08:46   #17
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
ho fatto cisì e sembra funzionare

Codice:
int array[100];
hMutex=CreateMutex(NULL, FALSE,NULL);

/* PRODUTTORE */


while(.....)
{
               WaitForSingleObject(hMutex,INFINITE);

/* SEZIONE CRITICA */

               for(int i=0; i<100; i++)
               array[i]=rand();

/* FINE SEZIONE CRITICA */

               ReleaseMutex(hMutex);
              Sleep(50);

}


/* CONSUMATORE */

while(.....)
{
               WaitForSingleObject(hMutex,INFINITE);

/* SEZIONE CRITICA */

               for(int i=0; i<100; i++)
               printf(%d\n,array[i]);

/* FINE SEZIONE CRITICA */

               ReleaseMutex(hMutex);
              Sleep(250);

}
difatti se a PRODUTTORE o a CONSUMATORE elimino ReleaseMutex(hMutex); l'altro thread non viene mai eseguito.

Mi chiedo però se la parte di codice sottostante a WaitForSingleObject(hMutex,INFINITE); viene eseguita completamente sino al ReleaseMutex(hMutex); ?
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 08:55   #18
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da misterx Guarda i messaggi
Mi chiedo però se la parte di codice sottostante a WaitForSingleObject(hMutex,INFINITE); viene eseguita completamente sino al ReleaseMutex(hMutex); ?
Non sono sicuro di aver capito cosa intendi dire.
Se e' quel che penso io, la risposta e' si', ovvero quando tu chiami WaitForSingleObject e qualcun altro l'ha gia' fatto, il thread resta in attesa finche' l'altro non chiama ReleaseMutex.
per cui solo uno alla volta dei due thread esegue la parte tra le due chiamate.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 14-04-2011, 09:22   #19
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Non sono sicuro di aver capito cosa intendi dire.
Se e' quel che penso io, la risposta e' si', ovvero quando tu chiami WaitForSingleObject e qualcun altro l'ha gia' fatto, il thread resta in attesa finche' l'altro non chiama ReleaseMutex.
per cui solo uno alla volta dei due thread esegue la parte tra le due chiamate.
hai capito benissimo, grazie per la conferma.

Ultima modifica di misterx : 18-04-2011 alle 05:57.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2011, 05:59   #20
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
c'è un aspetto che non avevo considerato: se ora devo riordinare in tempo reale una parte dell'array prima che venga usato da "consumatore" devo usare mutex ed un nuovo thread vero?
misterx è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


DJI Mavic 4 Pro: sblocca un nuovo livello per le riprese aeree DJI Mavic 4 Pro: sblocca un nuovo livello per le...
Idrogeno verde in Europa: nuovi studi prevedono costi ben superiori alle aspettative Idrogeno verde in Europa: nuovi studi prevedono ...
Mario Kart World lancia Switch 2: la magia Nintendo ora in 4K Mario Kart World lancia Switch 2: la magia Ninte...
La rivoluzione dei dati in tempo reale è in arrivo. Un assaggio a Confluent Current 2025 La rivoluzione dei dati in tempo reale è ...
SAP Sapphire 2025: con Joule l'intelligenza artificiale guida app, dati e decisioni SAP Sapphire 2025: con Joule l'intelligenza arti...
Apple Mac Mini con chip M4 scende ancora...
Tesla affonda a Wall Street: -30% nel 20...
iOS 18 è presente sull'82% di tut...
iPhone 17 a prezzi mai visti prima: camb...
Il monitor MSI PRO da 27 pollici a 120Hz...
Il tutorial di Switch 2 costa 10€, ma co...
L'iPhone senza porte di ricarica potrebb...
Internet of Underwater Things: Wsense e ...
Google Pixel Watch 2 scende a 149€: offr...
Xiaomi TV A 43'' 2025: a 229€ è u...
iOS 26 in arrivo ma questi iPhone non po...
iPhone 16e in offerta a 679€: cosa cambi...
Trump-Musk, la rottura è ufficial...
L'Europa vuole fare fuori Huawei dai cav...
Smartphone vietati anche alle superiori ...
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: 13:33.


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