View Full Version : [C/C++] Teorema del campionamento
ciao,
siccome ho scritto un programma che in definitiva è un campionatore, mi chiedevo se il teorema del campionamento è usabile anche nel mio caso.
Ho un thread che scansiona le porte di un apparato collegato via ethernet e riempe un array di 1024 byte.
Un secondo thread verifica se qualcuno dei suoi bit ha cambiato di stato: mi interessano i singoli bit, se a zero oppure ad uno.
Un terzo thread resta in attesa del secondo e se c'è qualcosa da scrivere su disco viene risvegliato.
Ho notato che i tempi di esecuzione tra i vari thread in windows XP sono dell'ordine di 1/3 millisecondi e quindi del tutto trascurabili per i miei scopi.
La domanda: se il dispositivo più veloce cambia il suo stato ogni 500 millisecondi ed io eseguo il primo thread ogni 250 millisecondi è garantito che riesco a catturare in modo preciso lo stato di tutti i bit dell'apparato?
E' un dubbio un pò forse banalotto ma non avendo esperienza vi chiedo conferme soprattutto in quanto ho verificato che lo scheduler di windows XP è veramente NON deterministico.
grazie 1000
La domanda: se il disositivo più veloce cambia il suo stato ogni 500 millisecondi ed io eseguo il primo thread ogni 250 millisecondi è garantito che riesco a catturare in modo preciso lo stato di tutti i bit dell'apparato?
Non ti serve il teorema del campionamento.
Se agisci cosi' ovviamente riuscirai a catturare il cambio di stato di un bit con "al piu'" 250 millisecondi di ritardo.
Non ti serve il teorema del campionamento.
Se agisci cosi' ovviamente riuscirai a catturare il cambio di stato di un bit con "al piu'" 250 millisecondi di ritardo.
quindi nel mio caso ritardare il secondo thread non servirebbe a nulla?
quindi nel mio caso ritardare il secondo thread non servirebbe a nulla?
Non capisco cosa significa "servire". Servire a cosa?
Se ogni segnale cambia al massimo ogni 500ms, e tu campioni ogni 250ms, non perderai alcuna informazione, ovvero avrai tutte le informazioni che ti servono, ma riceverai un cambio di segnale con un po' di ritardo, al piu' 250ms.
Non capisco cosa significa "servire". Servire a cosa?
Se ogni segnale cambia al massimo ogni 500ms, e tu campioni ogni 250ms, non perderai alcuna informazione, ovvero avrai tutte le informazioni che ti servono, ma riceverai un cambio di segnale con un po' di ritardo, al piu' 250ms.
il ritardo lo introduco per evitare di usare la CPU al 100%. Introducendo ritardi di 250 millisecondi, la CPU può dedicare il suo tempo a fare altro però il dubbio era se riuscivo ugualmente ad accorgermi che un bit era cambiato.
Ho notato che se calcolo il tempo di cambiamento di stato, per uno stesso bit, il tempo totale di variazione che leggo a volte è di 500 ms ed altre 750 ms, come se venissero sommati i 250 ms di attesa del secondo thread.
Continuando a diminuire il tempo di attesa del secondo thread sino a 5 ms la differenza rispetto ai 500 ms del cambiamento di stato sull'apparato si assottiglia, solo a volte leggo anzichè 500 ms, 516 ms
tomminno
01-08-2011, 11:38
La domanda: se il dispositivo più veloce cambia il suo stato ogni 500 millisecondi ed io eseguo il primo thread ogni 250 millisecondi è garantito che riesco a catturare in modo preciso lo stato di tutti i bit dell'apparato?
grazie 1000
Dato che stiamo parlando di sistemi operativi dotati di memoria virtuale non c'è garanzia che il thread venga risvegliato esattamente ogni 250 ms e che riesca a leggere i dati in tempo. Nel caso più catastrofico potrebbero verificarsi dei PageFault a cascata che rallentano l'esecuzione.
In ogni caso le periferiche generalmente hanno un buffer pertanto anche se la lettura arrivasse in ritardo dovresti trovare tutto.
Per riprova fai una lettura ogni 750ms, dovresti riuscire a leggere tutto quello che è stato inviato in precedenza.
Ma hai veramente necessità di uno sleep? Potresti semplicemente avere un thread che legge in continuazione dal socket con letture bloccanti (pertanto il thread rimane fermo nel caso in cui non ci siano dati in arrivo) e solleva eventi. Questi eventi verranno intercettati da una classe che conosce il protocollo di comunicazione e interpreta quando è arrivato un intero pacchetto logico di dati che a sua volta genererà altre azioni a seconda di quello che devi fare.
Dato che stiamo parlando di sistemi operativi dotati di memoria virtuale non c'è garanzia che il thread venga risvegliato esattamente ogni 250 ms e che riesca a leggere i dati in tempo. Nel caso più catastrofico potrebbero verificarsi dei PageFault a cascata che rallentano l'esecuzione.
In ogni caso le periferiche generalmente hanno un buffer pertanto anche se la lettura arrivasse in ritardo dovresti trovare tutto.
Per riprova fai una lettura ogni 750ms, dovresti riuscire a leggere tutto quello che è stato inviato in precedenza.
Ma hai veramente necessità di uno sleep? Potresti semplicemente avere un thread che legge in continuazione dal socket con letture bloccanti (pertanto il thread rimane fermo nel caso in cui non ci siano dati in arrivo) e solleva eventi. Questi eventi verranno intercettati da una classe che conosce il protocollo di comunicazione e interpreta quando è arrivato un intero pacchetto logico di dati che a sua volta genererà altre azioni a seconda di quello che devi fare.
nella mia situazione ho un thread che legge dati da ethernet e riempie un array di 1024 byte ogni tot millisecondi, questo perchè io non posso sapere quando cambia lo stato dei bit dell'apparato; questo è un compito che spetta al mio programma come spetta anche calcolare per quanto tempo è rimasto a zero oppure a uno ognuno dei suoi bit.
Siccome non so ogni quanto cambiano di stato i tali bit, ecco l'esigenza di uno sleep che liberasse la CPU per altri programmi, altrimenti avrei un uso della CPU pari al 100%
starfred
01-08-2011, 12:01
Come dice tomino non hai nessuna garanzia sulle temporizzazioni e quindi sulla deadline del thread che effettua la lettura. Anche se vai 100x più veloce prima o poi si potrebbero creare una serie di eventi che farà saltare il ciclo di lettura.
Se non ti ho convito basta immaginare una semplice operazione di I/O su disco di una primitiva di sistema con massima priorità, se dura più di 500ms sei "fritto". (Ho ipotizzato uno scheduler di tipo prioritario ma si può fare lo stesso con uno di time sharing).
A questo punto bisogna verificare se per te il salto di un ciclo di lettura è catastrofico oppure no, ovvero se si sta parlando di processi (nel tuo caso thread) di tipo hard o soft.
Poiché quello che a te interessa è la schedulazione di task periodici di una applicazione real-time, ti consiglio di guardare i seguenti standart per lo sviluppo di applicazioni real-time:
rt-posix
osek
apex
uITRON
Buona lettura. :D
Prova ad usare i Multimedia Timer invece che quelli forniti dal Framwork, sembrano essere piu' precisi.
http://www.softwareinteractions.com/blog/2009/12/7/using-the-multimedia-timer-from-c.html
Io organizzerei cosi', il thread che legge la porta Ethernet appende i 1024 risultati in un List<byte[]>, ogni immagine.
quello che legge i risultati parte dal presupposto che ognuno dei byte[] e' spiazzato di esattamente 500ms, e non parte ricaclolando i tempi, ma li da gia' per spiazzati esattamente quanto impostato dal timer di lettura.
Windows non e' come detto un sistema operativo real time, ma questi multimedia timer sembrano essere sufficientemente precisi.
Dai anche un'altra priorita' al tuo processo, per favorirlo nelle schedulazioni.
System.Diagnostics.Process.GetCurrentProcess().PriorityClass =
System.Diagnostics.ProcessPriorityClass.High;
banryu79
01-08-2011, 12:05
Ho notato che se calcolo il tempo di cambiamento di stato, per uno stesso bit, il tempo totale di variazione che leggo a volte è di 500 ms ed altre 750 ms, come se venissero sommati i 250 ms di attesa del secondo thread.
come già detto da gugoXX:
Se ogni segnale cambia al massimo ogni 500ms, e tu campioni ogni 250ms, non perderai alcuna informazione, ovvero avrai tutte le informazioni che ti servono, ma riceverai un cambio di segnale con un po' di ritardo, al piu' 250ms.
A) quando il thread lettore rileva un tempo di cambiamento di 500 ms significa che è stato risvegliato dalla sleep e quindi ha effettuato la lettura subito dopo che il valore nel dispositivo è stato cambiato (cambia appunto ogni 500 ms).
B) quando invece rileva un tempo di cambiamento di 750 ms (500 + 250) significa che è stato risvegliato dalla sleep appena prima della successiva mutazione del valore nel dispositivo, quindi la leggerà dopo la prossima sleep, tra 250 ms (il ritardo si accumula rispetto al tempo rilevato all'ultima lettura).
Continuando a diminuire il tempo di attesa del secondo thread sino a 5 ms la differenza rispetto ai 500 ms del cambiamento di stato sull'apparato si assottiglia, solo a volte leggo anzichè 500 ms, 516 ms
Come sopra, nel caso A leggi 500, nel caso B leggi 516 ms anche se al più dovrebbe essere (500 + 5 = 505) per via del discorso che abbiamo fatto in un altro thread circa la granularità del timer di sistema in Windows di circa 16 millisec (o almeno è quello che penso succeda).
Come dice tomino non hai nessuna garanzia sulle temporizzazioni e quindi sulla deadline del thread che effettua la lettura. Anche se vai 100x più veloce prima o poi si potrebbero creare una serie di eventi che farà saltare il ciclo di lettura.
Se non ti ho convito basta immaginare una semplice operazione di I/O su disco di una primitiva di sistema con massima priorità, se dura più di 500ms sei "fritto". (Ho ipotizzato uno scheduler di tipo prioritario ma si può fare lo stesso con uno di time sharing).
A questo punto bisogna verificare se per te il salto di un ciclo di lettura è catastrofico oppure no, ovvero se si sta parlando di processi (nel tuo caso thread) di tipo hard o soft.
Poiché quello che a te interessa è la schedulazione di task periodici di una applicazione real-time, ti consiglio di guardare i seguenti standart per lo sviluppo di applicazioni real-time:
rt-posix
osek
apex
uITRON
Buona lettura. :D
ciao,
dopo innumerevoli prove so che XP non è nato per il real time però volevo riuscire lo stesso a quantificare i ritardi introdotti.
Il mio vincolo è scrivere su XP
Se ad esempio ho dei bit che cambiano di stato ogni 1,5 secondi anche XP va bene per effettuare tali misurazioni, ma con che grado di precisione forse dico, forse in più o meno 20 millisecondi.
banryu79
01-08-2011, 12:07
edit*
starfred
01-08-2011, 12:10
Allora considera che prima o poi il worst case si verificherà.
Il mio consiglio è quello di scrivere il programma rispondendo alla domanda:
"se un thread fa una sleep di 2 secondi, cosa succede?"
E poi renderlo immune a questo tipo di eventi gestendo l'eccezione.
Un altro consiglio è quello di utilizzare la temporizzazione (la sleep) su un solo thread e poi (attraverso sezioni critiche/monitor etc. etc.) gestire gli altri di conseguenza.
come già detto da gugoXX:
A) quando il thread lettore rileva un tempo di cambiamento di 500 ms significa che è stato risvegliato dalla sleep e quindi ha effettuato la lettura subito dopo che il valore nel dispositivo è stato cambiato (cambia appunto ogni 500 ms).
B) quando invece rileva un tempo di cambiamento di 750 ms (500 + 250) significa che è stato risvegliato dalla sleep appena prima della successiva mutazione del valore nel dispositivo, quindi la leggerà dopo la prossima sleep, tra 250 ms.
Come sopra, nel caso A leggi 500, nel caso B leggi 516 ms anche se al più dovrebbe essere (500 + 5 = 505) per via del discorso che abbiamo fatto in un altro thread circa la granularità del timer di sistema in Windows (o almeno è quello che penso succeda).
scusa ma detto così sembrerebbe che io stia calcolando solo il tempo di mandata in esecuzione dei vari thread e non quello dei vari cambiamenti di stato :(
Allora considera che prima o poi il worst case si verificherà.
Il mio consiglio è quello di scrivere il programma rispondendo alla domanda:
"se un thread fa una sleep di 2 secondi, cosa succede?"
E poi renderlo immune a questo tipo di eventi gestendo l'eccezione.
Un altro consiglio è quello di utilizzare la temporizzazione (la sleep) su un solo thread e poi (attraverso sezioni critiche/monitor etc. etc.) gestire gli altri di conseguenza.
tra il secondo ed il terzo ad esempio ho usato un evento, difatti il terzo è legato al secondo da questo.
Tra il primo thread ed il secondo ho usato un semaforo per evitare inconsistenza di dati.
Il mio problema ora sono i tempi che sembrano legati ai vari sleep ed è ciò che vorrei evitare
Comunque credo di aver capito la tua idea: metto un evento anche tra il primo e secondo thread e lascio l'evento tra secondo e terzo così, quando il primo ha riempito l'array risveglia il secondo ed il secondo che lo interpreta se trova delle differenze risveglia il terzo; e tutto viaggia cone velocità settata nel primo
banryu79
01-08-2011, 12:15
scusa ma detto così sembrerebbe che io stia calcolando solo il tempo di mandata in esecuzione dei vari thread e non quello dei vari cambiamenti di stato :(
Sì infatti.
Tu hai detto che hai introdotto la sleep solo per non occupare la CPU in maniera aggressiva.
Solo che così il thread lettore si atttiva e legge in un attimo restando dormiente (e cieco alle mutazioni nel dispositivo) per ben 250 millisecondi circa ogni volta.
Fai il contrario: il tuo thread lettore farà polling per 250 millis consecutivi per poi andare a nanna per, ad esempio, 20 millis.
scusa ma detto così sembrerebbe che io stia calcolando solo il tempo di mandata in esecuzione dei vari thread e non quello dei vari cambiamenti di stato :(
Non i tempi di esecuzione, ma la frequenza di campionamento.
Se campioni la porta ogni 500ms, avrai sempre e comunque una speranza di precisione a multipli di 500ms, ma di sicuro non di meno.
Magari il segnale passa da 0 a 1, resta a 1 per 2589 ms e poi torna a zero, ma tu leggendo la porta ogni 500ms penserai che sara' rimasto attivo per 3000ms, se ti va comunque bene. Non hai modo di raggiungere una precisione maggiore se non campionando la porta piu' frequentemente.
Evita di aggiungere altri errori in cascata. Leggi ogni 500ms, salva tutto (anche solo in memoria), e processa in seguito cio' che hai letto.
Questo se non ti serve reagire immediatamente ad un cambio di stato per fare altro ovviamente, il che non e' chiaro.
Sì infatti.
Tu hai detto che hai introdotto la sleep solo per non occupare la CPU in maniera aggressiva.
Solo che così il thread lettore si atttiva e legge in un attimo restando dormiente (e cieco alle mutazioni nel dispositivo) per ben 250 millisecondi circa ogni volta.
Fai il contrario: il tuo thread lettore farà polling per 250 millis consecutivi per poi andare a nanna per, ad esempio, 20 millis.
però scusa,
se creassi io un thread che cambia un bit ogni 500 ms e volessi testare con un altro thread ogni quanto varia tale bit e trovassi sempre 500 ms cosa implicherebbe?
starfred
01-08-2011, 12:44
La parola sempre è un po' azzardata. Come si può intendere sempre?
1 minuto? 1 ora? 1 giorno? E' troppo relativo. Questo tipo di programmazione deve essere corretto dal punto di vista teorico.
Bisogna sempre ricondursi al worst case (che prima o poi si verificherà) e gestire il sistema di conseguenza.
Prova ad immaginare un sistema con 3 thread che eseguono questa operazione per 1000 volte:
TH1: Sleep(10); signal(TH2); wait();
TH2: Sleep(10); signal(TH3); wait();
TH3: Sleep(10); signal(TH1); wait();
Segnati l'orario di inizio e fine rimarrai molto sorpreso dal risultato :D
ciao,
siccome ho scritto un programma che in definitiva è un campionatore, mi chiedevo se il teorema del campionamento è usabile anche nel mio caso.
Ho un thread che scansiona le porte di un apparato collegato via ethernet e riempe un array di 1024 byte.
Un secondo thread verifica se qualcuno dei suoi bit ha cambiato di stato: mi interessano i singoli bit, se a zero oppure ad uno.
Un terzo thread resta in attesa del secondo e se c'è qualcosa da scrivere su disco viene risvegliato.
Ho notato che i tempi di esecuzione tra i vari thread in windows XP sono dell'ordine di 1/3 millisecondi e quindi del tutto trascurabili per i miei scopi.
La domanda: se il dispositivo più veloce cambia il suo stato ogni 500 millisecondi ed io eseguo il primo thread ogni 250 millisecondi è garantito che riesco a catturare in modo preciso lo stato di tutti i bit dell'apparato?
E' un dubbio un pò forse banalotto ma non avendo esperienza vi chiedo conferme soprattutto in quanto ho verificato che lo scheduler di windows XP è veramente NON deterministico.
grazie 1000
nessun programma su xp ti assicurerà quello che chiedi in quanto il s.o. non è realtime
La parola sempre è un po' azzardata. Come si può intendere sempre?
1 minuto? 1 ora? 1 giorno? E' troppo relativo. Questo tipo di programmazione deve essere corretto dal punto di vista teorico.
Bisogna sempre ricondursi al worst case (che prima o poi si verificherà) e gestire il sistema di conseguenza.
Prova ad immaginare un sistema con 3 thread che eseguono questa operazione per 1000 volte:
TH1: Sleep(10); signal(TH2); wait();
TH2: Sleep(10); signal(TH3); wait();
TH3: Sleep(10); signal(TH1); wait();
Segnati l'orario di inizio e fine rimarrai molto sorpreso dal risultato :D
purtoppo non ho esperienza in programmazione di questo tipo :(
Ma come faccio a questo punto a capire se il tempo che leggo è quello di variazione del bit oppure dei vari sleep? :muro:
grossolanamente il codice è questo
byte buf[1024];
//TH1
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
RiempiArray(buf);
ReleaseMutex(hMutex);
Sleep(250);
}
//TH2
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
for(int i=0; i<1024; i++)
{
if(bit cambia stato)
calcola_tempo();
SetEvent ( hEvent2 );
}
ReleaseMutex(hMutex);
Sleep(50);
}
//TH3
while(1)
{
WaitForSingleObject(hEvent2 ,INFINITE);
Salva_Tempo();
ResetEvent( hEvent2 );
}
nessun programma su xp ti assicurerà quello che chiedi in quanto il s.o. non è realtime
ma non si riescono nemmeno a quantificare i ritardi introdotti da xp ?
starfred
01-08-2011, 13:36
Mi spiace ma non conosco il funzionamento di quelle funzioni quindi non ti saprei dire cose corrette; come mai hai scelto di utilizzare le MSDN Library?
Non puoi quantificare i ritardi per una valanga di motivi tra cui: non conosci il numero di processi, non conosci i tempi dei singoli processi, non conosci le deadline dei processi, non conosci lo scheduler, non conosci la priorità dei processi... etc. etc.
Mi spiace ma non conosco il funzionamento di quelle funzioni quindi non ti saprei dire cose corrette; come mai hai scelto di utilizzare le MSDN Library?
Non puoi quantificare i ritardi per una valanga di motivi tra cui: non conosci il numero di processi, non conosci i tempi dei singoli processi, non conosci le deadline dei processi, non conosci lo scheduler, non conosci la priorità dei processi... etc. etc.
ok, grazie 1000 a tutti
Sto facendo alcune prove e noto ritardi di al massimo 15 millisecondi tra una lettura l'altra.
I dati reali mi sono stati forniti dal costruttore del dispositivo e dove viene dichiarato 1 secondo io leggo a volte 1,015 = 1015 ms
ma non si riescono nemmeno a quantificare i ritardi introdotti da xp ?
spannometricamente oltre 1s di tempo ciclo l'influenza del sistema operativo diventa trascurabile
spannometricamente oltre 1s di tempo ciclo l'influenza del sistema operativo diventa trascurabile
forse anche 0.5 s ???
Ho notato una certa ripetibilità dopo centinaia di migliaia di misurazioni vie ethernet dove il massimo ritardo che ho registrato sono 15 ms che guarda caso sembrano proprio quelli che inserisco io come pausa tra i thread.
starfred
01-08-2011, 14:40
Prova a stressare di tanto la macchina e poi effettua il test. Che tempi ci sono?
nella mia situazione ho un thread che legge dati da ethernet e riempie un array di 1024 byte ogni tot millisecondi, questo perchè io non posso sapere quando cambia lo stato dei bit dell'apparato; questo è un compito che spetta al mio programma come spetta anche calcolare per quanto tempo è rimasto a zero oppure a uno ognuno dei suoi bit.
Ma l'apparato manda lui i dati ogni tot millisecondi oppure sei tu che ogni tot fai uan richiesta sulla rete e ottieni risposta ?
Siccome non so ogni quanto cambiano di stato i tali bit, ecco l'esigenza di uno sleep che liberasse la CPU per altri programmi, altrimenti avrei un uso della CPU pari al 100%
In ogni caso se il problema e' quello dell'occupazione della cpu, avrebbe molto piu' senso che il secondo thread rimanga in attesa e venga risvegliato solo quando almeno uno dei 1024 byte viene cambiato (il confronto non dovrebbe occupare molto tempo).
Tieni inoltre presente che se tu fai una sleep di 500 ms, l'esecuzione non avviene ogni mezzo secondo, perche' ci devi aggiungere anche il tempo di esecuzione tra una sleep e l'altra. Dovresti schedulare una sleep di (500 - tempo appena consumato) (oppure una schedulazione ricorrente, se il sistema operativo lo supporta).
Prova a stressare di tanto la macchina e poi effettua il test. Che tempi ci sono?
provo a lanciare 5 processi uguali
La domanda: se il dispositivo più veloce cambia il suo stato ogni 500 millisecondi ed io eseguo il primo thread ogni 250 millisecondi è garantito che riesco a catturare in modo preciso lo stato di tutti i bit dell'apparato?
Si', ma te ne accorgi con un ritardo che puo' anche arrivare a 250 ms (perche' se e' cambiato giusto appena dopo che eri entrato nella sleep.)
E' un dubbio un pò forse banalotto ma non avendo esperienza vi chiedo conferme soprattutto in quanto ho verificato che lo scheduler di windows XP è veramente NON deterministico.
Tieni presente il discorso che ho fatto sopra sulla durata della sleep. Per come l'hai impostato, il tuo ciclo non ha durata 250 ms, ma 250+X con X il tempo di esecuzione del codice del loop. La cosa peggiora ancora di piu' se per qualche motivo il ciclo viene messo in pausa per qualche motivo nel mezzo della sua esecuzione.
starfred
01-08-2011, 14:49
Io intendo una situazione di sovraccarico; hai presente quando il mouse si muove a scatti? :D
Prova a fare il test mentre usi un programma di stress pesante della cpu e I/O
una volta che si è assestato il programma in quanto allo start i tempi sono randomici, il ritardo che leggo è +/- 16 millisecondi
Ma l'apparato manda lui i dati ogni tot millisecondi oppure sei tu che ogni tot fai uan richiesta sulla rete e ottieni risposta ?
In ogni caso se il problema e' quello dell'occupazione della cpu, avrebbe molto piu' senso che il secondo thread rimanga in attesa e venga risvegliato solo quando almeno uno dei 1024 byte viene cambiato (il confronto non dovrebbe occupare molto tempo).
Tieni inoltre presente che se tu fai una sleep di 500 ms, l'esecuzione non avviene ogni mezzo secondo, perche' ci devi aggiungere anche il tempo di esecuzione tra una sleep e l'altra. Dovresti schedulare una sleep di (500 - tempo appena consumato) (oppure una schedulazione ricorrente, se il sistema operativo lo supporta).
sono io che impongo il tempo di lettura per non sovraccaricare la CPU.
Ho provato anche ad implementare due CreateEvent() in modo che il TH1 risvegliasse TH2 quando questo ha finito di leggere da ethernet ma nulla vieta poi a TH1 se non metto un semaforo, di fare una nuova lettura da ethernet rendendo i dati nel buffer analizzato in quel momento da TH2 inconsistenti.
Io intendo una situazione di sovraccarico; hai presente quando il mouse si muove a scatti? :D
Prova a fare il test mentre usi un programma di stress pesante della cpu e I/O
lancio un rendering
sono io che impongo il tempo di lettura per non sovraccaricare la CPU.
Ho provato anche ad implementare due CreateEvent() in modo che il TH1 risvegliasse TH2 quando questo ha finito di leggere da ethernet ma nulla vieta poi a TH1 se non metto un semaforo, di fare una nuova lettura da ethernet rendendo i dati nel buffer analizzato in quel momento da TH2 inconsistenti.
Intendevo dire, visto che gia' usi un mutex per regolare l'accesso, potresti fare si' che sia il primo thread a fare il confronto e rilasci il mutex solo se e' cambiato qualcosa
a questo punto il secondo thread viene eseguito solo quando serve.
sono io che impongo il tempo di lettura per non sovraccaricare la CPU.
Ho provato anche ad implementare due CreateEvent() in modo che il TH1 risvegliasse TH2 quando questo ha finito di leggere da ethernet ma nulla vieta poi a TH1 se non metto un semaforo, di fare una nuova lettura da ethernet rendendo i dati nel buffer analizzato in quel momento da TH2 inconsistenti.
E fagli scrivere da un'altra parte...
Tieni una coda di serie di letture.
Il thread che legge accoda una serie nuova e un riferimento utile per capire quando la lettura e' avvenuta, un semplice sequenziale. Quando e' 42, singifichera' che la serie si riferisce al 42*512ms = 21 secondi dalla partenza, (fatti salve le inaccuratezze di schedulazione fin qui esposte)
Il thread che processa i dati scoda e analizza, con molta calma, quando piu' gli fa comodo.
In questo modo non hai neppure bisogno di mutex se non per accodare-scodare, cosa comunque molto light e gia' anche implementata gratis se usi una System.Collections.Concurrent.ConcorrentQueue<T>
Intendevo dire, visto che gia' usi un mutex per regolare l'accesso, potresti fare si' che sia il primo thread a fare il confronto e rilasci il mutex solo se e' cambiato qualcosa
a questo punto il secondo thread viene eseguito solo quando serve.
ma il primo riempie un buffer e non può sapere a priori se è cambiato qualcosa. Solo il secondo se ne accorge ed in questo caso se è cambiato qualcosa è il secondo che risveglia il terzo attraverso un evento in modo che scriva su disco il tempo calcolato.
Tra primo e secondo cè un semaforo per evitare inconsistenza di dati nel buffer e tra il secondo ed il terzo un evento che sempre il terzo, una volta sodisfatto resetta.
E fagli scrivere da un'altra parte...
Tieni una coda di serie di letture.
Il tread che legge accoda una serie nuova e un riferimento utile per capire quando la lettura e' avvenuta, un semplice sequenziale. Quando e' 42, singifichera' che la serie si riferisce al 42*512ms = 21 secondi dalla partenza, (fatti salve le inaccuratezze di schedulazione fin qui esposte)
Il thread che processa i dati scoda e analizza, con molta calma, quando piu' gli fa comodo.
ma per come è costruita la funzione di lettura, io passo un puntatore ad un buffer e questa lo riempie ed ogni volta il ciclo si ripete allo stesso modo ogni tot millisecondi da me imposti.
Non mi viene in mente come accodare
ho allegato il simulatore che si basa sul medesimo principio: è per Borland Builder C++ ma facilemnet adattabile
ma per come è costruita la funzione di lettura, io passo un puntatore ad un buffer e questa lo riempie ed ogni volta il ciclo si ripete allo stesso modo ogni tot millisecondi da me imposti.
Non mi viene in mente come accodare
dipende da come e' scritta la funzione di lettura.
Se e' una funzione di lettura e basta, giusto prima di chiamarla potresti fare una new di 1024 byte, passare alla funzione il nuovo puntatore e accodare il risultato ripempito nella coda condivisa.
dipende da come e' scritta la funzione di lettura.
Se e' una funzione di lettura e basta, giusto prima di chiamarla potresti fare una new di 1024 byte, passare alla funzione il nuovo puntatore e accodare il risultato ripempito nella coda condivisa.
è una funzione di libreria scritta dal produttore dell'apparato e al massimo posso giocare sul buffer.
In pagina 2 ho allegato il simulatore
è una funzione di libreria scritta dal produttore dell'apparato e al massimo posso giocare sul buffer.
In pagina 2 ho allegato il simulatore
Si', ma a quel simulatore puoi far fare quello che vuoi, anche cose che potenzilamente potresti non poter fare, e ovviamente non fa testo.
E comunque giocare sul buffer, l'unica cosa che puoi fare, e' proprio quello che proponevo di fare.
PRIMA di chiamare la funzione di lettura (che non e' ovviamente presente nel simulatore), allochi 1024 bytes e passi il nuovo puntatore alla funzione.
Ottenuto il risultato accodi il tutto in una coda condivisa che ovviamente nel simulatore non c'e'.
E il consumatore leggera' dalla coda condivisa quando piu' gli fa comodo.
marco.r,
quasi quasi se implemento solo due thread mi semplifico la vita.
//TH1
- riempio buffer da ethernet
- ciclo buffer se cambiato qualcosa creo evento e risveglio TH2
//TH2
- vislualizza e memorizza su disco
Si', ma a quel simulatore puoi far fare quello che vuoi, ovviamente non fa testo.
perhè non ho di mezzo la ethernet?
Si', ma a quel simulatore puoi far fare quello che vuoi, anche cose che potenzilamente potresti non poter fare, e ovviamente non fa testo.
E comunque giocare sul buffer, l'unica cosa che puoi fare, e' proprio quello che proponevo di fare.
PRIMA di chiamare la funzione di lettura (che non e' ovviamente presente nel simulatore), allochi 1024 bytes e passi il nuovo puntatore alla funzione.
Ottenuto il risultato accodi il tutto in una coda condivisa che ovviamente nel simulatore non c'e'.
E il consumatore leggera' dalla coda condivisa quando piu' gli fa comodo.
però se il buffer viene elaborato quando più fa comodo, come determino i tempi di cambiamento di stato da zero a uno e viceversa?
Il mio problema è determinare il cambiamento di stato e il tempo di permamenza in tale stato
banryu79
01-08-2011, 15:57
Il mio problema è determinare il cambiamento di stato e il tempo di permamenza in tale stato
E questo implica che c'è bisogno di un thread per fare "polling continuo", o sbaglio?
Sapendo che i valori/bit del dispositivo sono N, io teoricamente farei così:
a) polling continuo con il thread Lettore:
- ha un buffer di N elementi;
- prima lettura in avvio: copia lo stato del dispositivo nel buffer;
- ciclo infinito, ad ogni iterazione:
- se i valori che legge nel dispositivo sono diversi da quelli presenti nel buffer
- copia i valori del dispositivo nel buffer (per futuri confronti)
- fa una copia del buffer Copia;
- crea un Elemento con Copia e un timestamp (per consumo da parte del thread Scrittore);
- acquisisce mutex di Coda;
- infila Elemento nella Coda;
- rilascia mutex di Coda;
- sleep brevissima
b) una struttura che faccia da Coda, condivisa con una mutex
c) thread Scrittore (con parametro X tarabile: numero di elementi da estrarre dalla Coda ad ogni iterazione)
- ciclo infinito, ad ogni iterazione:
- acquisisce mutex di Coda;
- rimuovi al più X Elementi da Coda;
- rilascia mutex di Coda;
- scrivi al più X Elementi su file;
- sleep moderata
@EDIT:
Invece di "salvare" tutto il buffer, se si salva in avvio lo stato iniziale del dispositivo (snapshot) poi si possono salvare solo le differenze (i delta).
Magari ogni tanto (se neccessario o si ritiene sia conveniente) si può fare un nuovo snapshot per poi continuare con i soli delta.
E questo implica che c'è bisogno di un thread per fare "polling continuo", o sbaglio?
Sapendo che i valori/bit del dispositivo sono N, io teoricamente farei così:
a) polling continuo con il thread Lettore:
- ha un buffer di N elementi;
- prima lettura in avvio: copia lo stato del dispositivo nel buffer;
- ciclo infinito, ad ogni iterazione:
- se i valori che legge nel dispositivo sono diversi da quelli presenti nel buffer
- copia i valori del dispositivo nel buffer (per futuri confronti)
- fa una copia del buffer Copia;
- crea un Elemento con Copia e un timestamp (per consumo da parte del thread Scrittore);
- acquisisce mutex di Coda;
- infila Elemento nella Coda;
- rilascia mutex di Coda;
- sleep brevissima
b) una struttura che faccia da Coda, condivisa con una mutex
c) thread Scrittore (con parametro X tarabile: numero di elementi da estrarre dalla Coda ad ogni iterazione)
- ciclo infinito, ad ogni iterazione:
- acquisisce mutex di Coda;
- rimuovi al più X Elementi da Coda;
- rilascia mutex di Coda;
- scrivi al più X Elementi su file;
- sleep moderata
aspetta scusa: la funzione che sto usando richiede un buffer di dimensione nota e lei la riempie
Inizialmente avevo tre thread con un semaforo comune tra produttore e consumatore ed un evento tra consumatore e scrittore.
Poi mi sono detto se ne valeva la pena mantenere un semaforo in quanto:
se produttore sta riempiendo consumatore non può accedervi e allora tanto vale eliminare consumatore e mettere in sequenza i due
//produttore
-------- riempe array
-------- cicla array e se trova bit a uno crea evento
//scrittore
----- attesa_evento
----- scrive tempi su disco
----- resetta evento
ma non so se ho fato bene ad eliminare consumatore, di primo acchito direi di si.
Sta di fatto che continuo a notare differenze di al max 20 millisecondi: forse significa che windows in determinate condizioni può essere usato a scopo real time?
banryu79
01-08-2011, 16:52
Sta di fatto che continuo a notare differenze di al max 20 millisecondi: forse significa che windows in determinate condizioni può essere usato a scopo real time?
Che io sappia no, non ci si può appoggiare a Windows assumendo di avere a che fare con un sistema real time, perchè non lo è.
Che io sappia no, non ci si può appoggiare a Windows assumendo di avere a che fare con un sistema real time, perchè non lo è.
non avendo mai scritto programmi per sistemi operativi real time, anche se la risposta sembrerebbe scontata significa che se portassi il mio programma così com'è sotto un sistema operativo real time avrei tempi corretti?
un link che non è chiarissimo se intendano che windows 2000/xp possono diventare RT http://www.codeguru.com/cpp/w-p/system/messagehandling/article.php/c14457
non avendo mai scritto programmi per sistemi operativi real time, anche se la risposta sembrerebbe scontata significa che se portassi il mio programma così com'è sotto un sistema operativo real time avrei tempi corretti?
un link che non è chiarissimo se intendano che windows 2000/xp possono diventare RT http://www.codeguru.com/cpp/w-p/system/messagehandling/article.php/c14457
un sistema con un os. real time ti garantisce che il tuo codice girerà effettivamente ad una determinata frequenza: io uso spessissimo rtos su un pxi per fare acquisizione e controllo ma ha il difetto di essere piuttosto caro e di dover programmare con quello schifo che è G con tanti ringraziamenti a ni
in alternativa se il programma è semplice puoi pensare di portare l'acquisizione su un micro, salvare i dati su flash e postelaborarli offline
un sistema con un os. real time ti garantisce che il tuo codice girerà effettivamente ad una determinata frequenza: io uso spessissimo rtos su un pxi per fare acquisizione e controllo ma ha il difetto di essere piuttosto caro e di dover programmare con quello schifo che è G con tanti ringraziamenti a ni
in alternativa se il programma è semplice puoi pensare di portare l'acquisizione su un micro, salvare i dati su flash e postelaborarli offline
scusa ed un qualcosa di più noto?
Ti risulta windows CE oppure Linux o anche Windows XP Embedded?
p.s
guardacaso qua dice di no http://it.wikipedia.org/wiki/Sistema_operativo_real-time
starfred
01-08-2011, 19:13
Un sistema operativo real-time ti può garantire con altissima probabilità (nulla è 100%) che lo scheduling dei processi avverrà nella deadline previste.
Il fatto che il tuo codice funzioni ora sulla tua macchina windows xp non garantisce affatto che funzioni su un 8-core con windows xp.
Non ti garantisce nemmeno che funzioni sulla tua macchina domani.
Un sistema operativo real-time ti può garantire con altissima probabilità (nulla è 100%) che lo scheduling dei processi avverrà nella deadline previste.
Il fatto che il tuo codice funzioni ora sulla tua macchina windows xp non garantisce affatto che funzioni su un 8-core con windows xp.
Non ti garantisce nemmeno che funzioni sulla tua macchina domani.
dopo tutto quello che ho letto ed ho provato sulla mia pellaccia sono convinto!
Meno male che il bit relativo al dispositivo più "veloce", si fa per dire, cambia in circa 1,5 secondi.
Ciò vuol dire che dovrei riuscire anche con XP a determinare abbastanza frequentemente e con buona precisione tale tempo.
Ho provato anche con bit che cambiano ogni 188 ms come esperimento e tali 188 ms che sono stati rilevati prima strumentalmente, grande mistero per me, leggo la maggior parte delle volte proprio 188 ms con un errore di (+/- 16 ms) solo a volte.
E' un fatto che non riuscirò mai a spiegarmi boh.
starfred
01-08-2011, 20:56
Un modo per evitare di fare tutta la storia delle temporizzazioni è quello di modificare il dispositivo in modo tale da effettuare un handshake con il thread nel momento in cui è pronto un nuovo dato.
Un modo per evitare di fare tutta la storia delle temporizzazioni è quello di modificare il dispositivo in modo tale da effettuare un handshake con il thread nel momento in cui è pronto un nuovo dato.
cioè il dispositivo mi dovrebbe dire quando ha dati da inviarmi?
Un metodo forse ci sarebbe ma non so se risolverebbe il problema. Mi pare che nel momento in cui viene fatto un refresh dei dati viene alzato un particolare bit.
dopo 3100 misurazioni ho ottenuto i seguenti risultati
A B C D
medie 401 199 600 797
max 422 204 610 797
min 390 187 593 719
ho scoperto solo ora di avere un grosso problema nella mia implementazione: quando TH2 setta l'evento, TH3 non risponde in maniera così decisiva e quindi si perde dati per strada in quanto nel tempo in cui TH3 stra per rispondere TH2 ha già modificato li buffer, che soluzioni ci potrebbero essere?
chari miobuf[80];
byte buf[1024];
//TH1
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
RiempiArray(buf);
ReleaseMutex(hMutex);
Sleep(250);
}
//TH2
while(1)
{
WaitForSingleObject(hMutex,INFINITE);
for(int i=0; i<1024; i++)
{
if(bit cambia stato)
calcola_tempo();
sprintf(miobuf,"%d.%d",a,b);
SetEvent ( hEvent2 );
}
ReleaseMutex(hMutex);
Sleep(50);
}
//TH3
while(1)
{
WaitForSingleObject(hEvent2 ,INFINITE);
fprintf(fp,"X%s\n",miobuf);;
ResetEvent( hEvent2 );
}
tomminno
02-08-2011, 16:21
ho scoperto solo ora di avere un grosso problema nella mia implementazione: quando TH2 setta l'evento, TH3 non risponde in maniera così decisiva e quindi si perde dati per strada in quanto nel tempo in cui TH3 stra per rispondere TH2 ha già modificato li buffer, che soluzioni ci potrebbero essere?
Ma il buffer lo copi oppure ti passi un puntatore/riferimento?
Ma il buffer lo copi oppure ti passi un puntatore/riferimento?
in TH2 uso la sprintf(miobuf,"%d.%d",a,b); con miobuf che è un array globale
tomminno
02-08-2011, 17:08
in TH2 uso la sprintf(miobuf,"%d.%d",a,b); con miobuf che è un array globale
:nono: :incazzed:
è la soluzione più immediata
provo a vedere qualcosa sulle code anche se mi ricordo poco di queste strutture dati
:nono: :incazzed:
ovviamente è un adattamento a codice già esistente ma non sono convinto che risolva il mio problema.
Che lunghezza deve avere la coda?
Una lunghezza dinamica?
E se qualche funzione si pianta e continua ad allocare che succede?
Tutte problematiche che un array statico evita IMHO
Ora la nuvoletta dovrebbe rasserenarsi :)
/* Implementazione della Coda */
#define DIMCODA 20 /*1*/
typedef struct {
double par1;
double par2;
double par3;
}sensore;
sensore sensori[DIMCODA];
int fondo = -1;
int testa = -1;
/* Funzioni per la gestione della Coda */
int piena(); /*2*/
int vuota();
void aggiungi(sensore sens);
sensore elimina();
/* Funzioni che ritornano informazioni sullo stato della coda */
int piena(){
int numel;
numel=(fondo>=testa)?(fondo-testa):(fondo+DIMCODA-testa); /*3*/
if(numel==DIMCODA-1) /*4*/
return 1;
else
return 0;
}
int vuota(){
if(testa==fondo) /*5*/
return 1;
else
return 0;
}
/* Funzioni standard per la gestione di una coda */
/* Aggiunge un elemento alla coda */
void aggiungi(sensore sens){
fondo = ++fondo % DIMCODA; /*6*/
sensori[fondo]=sens; /*7*/
}
/* Elimina un elemento dalla coda */
sensore elimina(){
testa = ++testa % DIMCODA; /*8*/
return sensori[testa]; /*9*/
}
comunque anche con una coda il problema della perdita di dati non si risolve affatto.
Ora i thread sono diventati solo due:
TH1: produttore/consumatore
TH2: scrittore
consumatore riempe un buffer e crea un evento che purtroppo viene sentito da scrittore solo quando gli pare.
Inserendo uno sleep() le cose migliorano, ma quanto deve valere tale sleep?
Che caos :D
Tanto vale mettere tutto in sequenza e far viaggiare tutto il processo alla velocità del disco :muro:
oramai parlo da solo però volevo in un certo senso concludere dicendo che la soluzione migliore che ho trovato con due thread è l'uso degli EVENTI mantenendo la sprintf() che semplifica la vita :)
banryu79
03-08-2011, 07:32
consumatore riempe un buffer e crea un evento che purtroppo viene sentito da scrittore solo quando gli pare.
Ciao, scusa, ma se TH1 all'evento accoppiasse un timestamp del momento in cui lo rileva, e infilasse questa informazione nella coda poi non importa più quando TH2 lo pesca per processarlo... o no?
Ciao, scusa, ma se TH1 all'evento accoppiasse un timestamp del momento in cui lo rileva, e infilasse questa informazione nella coda poi non importa più quando TH2 lo pesca per processarlo... o no?
scusa ma non ho capito la tua soluzione :stordita:
banryu79
03-08-2011, 08:26
scusa ma non ho capito la tua soluzione :stordita:
Niente, forse sono io che non ho capito il problema, facevo riferimento allo schemino che avevo postato un paio di pagine fa (continuno polling del dispositivo e salvataggio dello stato con accodamento solo in caso di mutazione, secondo thread che scoda e scrive su disco)
Ma ho visto che sai passato ad altro; per tornare alla tua situazione (intendo quella che hai descritto al post #58 con i tre thread):
ho scoperto solo ora di avere un grosso problema nella mia implementazione: quando TH2 setta l'evento, TH3 non risponde in maniera così decisiva e quindi si perde dati per strada in quanto nel tempo in cui TH3 stra per rispondere TH2 ha già modificato li buffer, che soluzioni ci potrebbero essere?
Noto che TH1 va in sleep per 250 ms mentre TH2 va in sleep per 50 ms e entrambi si sincronizzano sulla stessa mutex con TH1 che scrive su buf e TH2 che legge da buf.
Alcune considerazioni (non vedendo il codice vero e proprio è meglio non dare niente per scontato o ci si fraintende):
-> assumo che rispetto allo pseudo codice da te postato TH2 setti l'evento fuori dal cilclo for, e non a ogni iterazione, altrimenti io in questo vedo già un problema (non mi pare abbia senso star li a controllare e a segnalare la mutazione del singolo bit di stato, dato che leggiendo dal dispositivo ogni 250 ms non vedi cmabiamenti "istantanei" dei bit ma solo le "fotografie" di tutto lo stato ad intervalli regolari)
-> dato che TH1 aggiorna ogni circa 250 ms lo stato di buf e TH2 lo legge circa ogni 50 ms (quindi assumiamo spannometricamente che in media buf venga letto da TH2 almeno 3-4 volte prima di essere nuovamente aggiornato) TH2 quando ha il mutex e legge buf deve avere una suo copia interna dello stesso e andare a verificare se la sua copia interna è diversa da buf (vuol dire che buf è stato aggiornato) prima di stabilire che lo stato è cambiato e segnalarlo con un evento a TH3, altrimenti rischi che TH2 segnali più volte la stessa mutazione...
Per la considerazione fatta qui sopra, allora non è forse più opportuno sincronizzare TH1 e TH2 tra loro con un evento (che solleva TH1, quindi lo solleva una volta ogni circa 250 ms) per poi sincronizzare TH2 e Th3 con una mutex?
Ripeto: forse sono io che non ho capito il problema, anche perchè non sono un esperto e non ho una conoscenza diretta del problema, spero petanto di averti dato uno spunto di riflessione e non uno di confusione :)
Niente, forse sono io che non ho capito il problema, facevo riferimento allo schemino che avevo postato un paio di pagine fa (continuno polling del dispositivo e salvataggio dello stato con accodamento solo in caso di mutazione, secondo thread che scoda e scrive su disco)
Ma ho visto che sai passato ad altro; per tornare alla tua situazione (intendo quella che hai descritto al post #58 con i tre thread):
Noto che TH1 va in sleep per 250 ms mentre TH2 va in sleep per 50 ms e entrambi si sincronizzano sulla stessa mutex con TH1 che scrive su buf e TH2 che legge da buf.
Alcune considerazioni (non vedendo il codice vero e proprio è meglio non dare niente per scontato o ci si fraintende):
-> assumo che rispetto allo pseudo codice da te postato TH2 setti l'evento fuori dal cilclo for, e non a ogni iterazione, altrimenti io in questo vedo già un problema (non mi pare abbia senso star li a controllare e a segnalare la mutazione del singolo bit di stato, dato che leggiendo dal dispositivo ogni 250 ms non vedi cmabiamenti "istantanei" dei bit ma solo le "fotografie" di tutto lo stato ad intervalli regolari)
-> dato che TH1 aggiorna ogni circa 250 ms lo stato di buf e TH2 lo legge circa ogni 50 ms (quindi assumiamo spannometricamente che in media buf venga letto da TH2 almeno 3-4 volte prima di essere nuovamente aggiornato) TH2 quando ha il mutex e legge buf deve avere una suo copia interna dello stesso e andare a verificare se la sua copia interna è diversa da buf (vuol dire che buf è stato aggiornato) prima di stabilire che lo stato è cambiato e segnalarlo con un evento a TH3, altrimenti rischi che TH2 segnali più volte la stessa mutazione...
Per la considerazione fatta qui sopra, allora non è forse più opportuno sincronizzare TH1 e TH2 tra loro con un evento (che solleva TH1, quindi lo solleva una volta ogni circa 250 ms) per poi sincronizzare TH2 e Th3 con una mutex?
Ripeto: forse sono io che non ho capito il problema, anche perchè non sono un esperto e non ho una conoscenza diretta del problema, spero petanto di averti dato uno spunto di riflessione e non uno di confusione :)
ciao,
non pochi, ma molti spunti di riflessione mi avete fornito in questo thread.
Contrariamente a quanto scrivi io l'evento lo setto propio ad ogni ciclo del for() questo allo scopo di catturare la variazione di ogni singoli bit in quanto a me interessa il singolo bit.
Ripensando ogni volta a quanto stavo facendo ora i thread sono rimasti solo due in quanto, in una versione precedente avevo usato 3 thread, mutex ed evento ma i conti non mi tornavano affatto.
Il primo thread riempiva un buffer, il secondo lo analizzava ed il terzo ne stampava il risultato.
Per non avere inconsistenza avevo interposto un mutex tra il primo thread ed il secondo ma a questo punto mi sono detto: se il primo aspetta ogni volta il secondo per evitare inconsistenza tanto vale mettere le cose in sequenza.
Allo stato attuale ora mi ritrovo col seguente schema che sembra stia funzionando bene:
//TH1
- riempie buffer
- cicla buffer alla ricerca dello stato dei suoi bit, se cambia qualche bit genera evento per TH2 e si mette in attesa di un evento questa volta generato da TH2
//TH2
- attende TH1
- scrive i dati su disco
- resetta evento generato da TH1
- risveglia TH1
Fatto ciclare i programma per 100000 volte le scritture su disco sono avvenute 6000 volte e cioè significa che su 100000 cicli hano cambiato di stato 6000 bit.
Per curiosità ho inserito anche due contatori per capire se tutti i bit che trovavo venivano effettivamente scritti su disco in quanto magari mi poteva sfuggire un qualche ritardo tra i thread ed invece con sorpresa tutti i bit trovati cambiati vengono scritti.
Di sicuro ci sono soluzioni migliori della mia che reputo poco raffinata in quanto non ho esperienza in programmazione di questo tipo e ahimè molte cose dell'uni me le sto dimenticando :muro:
scusa ed un qualcosa di più noto?
Ti risulta windows CE oppure Linux o anche Windows XP Embedded?
p.s
guardacaso qua dice di no http://it.wikipedia.org/wiki/Sistema_operativo_real-time
di più noto di labview su hw dedicato realtime national instruments non c'è nulla :D :D :D è la soluzione più usata in assoluto per sviluppo e prototipazione ma ha dei costi che sono allucinanti (calcola almeno 5-6k€) ma per il tuo uso mi pare che sia come sparare ad una mosca con un railgun
cmq ne xp embedded ne windows ce sono realtime mentre per linux ci sono alcune distribuzioni realtime (anni va avevo visto linux rti ma non so se è ancora sviluppata)
l'alternativa è usare una scheda a microcontrollore che non avendo il sistema operativo ed eseguendo solo il tuo codice è praticamente deterministica nei tempi (a meno di int strani ma che puoi sempre gestire)
grazie !fazz,
momentaneamente sono obbligato a rimanere su XP.
Ho un dubbio che mi perseguita circa gli eventi questo dubbio nasce in quanto mi è sembrato di notare una situazione di stallo tra due thread; se chiamo:
ResetEvent(TH2);
SetEvent(TH1);
una dopo l'altra, potrebbe accadere che per tempistiche a me ignote entrambi i thread rimangono in attesa in quanto le due chiamate sopra non sono state sentite dai rispettivi thread?
scrivendo ResetEvent(TH2) il thread scrittore si rimette in attesa e subito dopo scrivendo SetEvent(TH1) il thread produttore/consumatore riparte.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.