|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#61 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
|
|
|
|
|
|
#62 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
è la soluzione più immediata
provo a vedere qualcosa sulle code anche se mi ricordo poco di queste strutture dati Ultima modifica di misterx : 02-08-2011 alle 19:51. |
|
|
|
|
|
#63 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
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 Codice:
/* 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*/
}
Ultima modifica di misterx : 02-08-2011 alle 21:43. |
|
|
|
|
|
#64 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
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 Tanto vale mettere tutto in sequenza e far viaggiare tutto il processo alla velocità del disco |
|
|
|
|
|
#65 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
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
|
|
|
|
|
|
#66 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
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?
__________________
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) |
|
|
|
|
|
#67 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
|
|
|
|
|
|
#68 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
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): Quote:
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
__________________
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) Ultima modifica di banryu79 : 03-08-2011 alle 09:30. |
|
|
|
|
|
|
#69 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
Quote:
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 |
|
|
|
|
|
|
#70 | |
|
Moderatore
Iscritto dal: Nov 2006
Messaggi: 21893
|
Quote:
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)
__________________
"WS" (p280,cx750m,4790k+212evo,z97pro,4x8GB ddr3 1600c11,GTX760-DC2OC,MZ-7TE500, WD20EFRX) Desktop (three hundred,650gq,3800x+nh-u14s ,x570 arous elite,2x16GB ddr4 3200c16, rx5600xt pulse P5 1TB)+NB: Lenovo p53 i7-9750H,64GB DDR4,2x1TB SSD, T1000 |
|
|
|
|
|
|
#71 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
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. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:47.




















