Newsgroup: it.comp.lang.c++
Titolo: Alla ricerca di un modello

Salve a tutti,
sono alla ricerca di un paradigma per un programma che voglio scrivere - e 
che implementero' in C++. Questo problema deriva da un progetto che sviluppo 
per hobby, ed e' anche un ottimo pretesto per migliorare il mio C++ e la mia 
capacita' di scrivere software :)
Il problema:
un programma su pc coordina uno sciame di sensori, con scambio dati 
bidirezionale (via radio, ma questo e' ininfluente). Il programma ha 
un'interfaccia grafica, attraverso la quale l'utente sceglie delle azioni 
(che causano la trasmissione di pacchetti dati verso i sensori); i sensori 
stessi, in modo asincrono e imprevedibile, generano pacchetti dati che 
vengono spediti al pc (che causano l'aggiornamento delle strutture dati, 
l'aggioramento dello schermo attraverso cui l'utente controlla la 
situazione, ecc.)
Domanda:
qual e' un paradigma di programmazione opportno per trattare questo genere 
di problemi?
Da progettista hardware mi viene facile pensarla in termini di una Finite 
State Machine, il cui stato interno e' lo stato delle strutture dati, e le 
cui transizioni sono triggerate dagli eventi. Non so come tradurre questo 
modello in software.
Il mio problema principale e' capire come fare a gestire questi eventi 
imprevedibili - dall'utente da una parte, dai pacchetti dati dall'altra.
Googolando in giro ho trovato parole come "event-driven programming", che 
sembra descrivere abbastanza il mio problema. Mi confermate? O e' una cosa 
diversa? Avete qualche referenza da indicarmi su cui studiare?
Thx,
Pleg
PS: ho parlato di interfaccia grafica - questo e' un punto totalmente aperto 
per me, mai fatta una neanche da lontano (e credo sia ora di cominciare ad 
imparare le basi :). Sempre googolando, penso che Qt possa fare al caso 
mio... e per certi versi mi sembra che il modello di programmazione di una 
GUI si applichi anche alla parte del mio programma che gestisce i sensori - 
sono tutti eventi asincroni, a cui rispondere chiamando funzioni opportune e 
aggiornando delle strutture dati.
Confermate questa mia impressione?

 
Confermo e ti dico anche che le Qt potrebbero tornarti utile non solo 
per l'interfaccia grafica.
Maurus

 critiche....)
Ecco, questo e' un punto che non ho chiaro: io pensavo (in astratto, come ho 
detto non so come mappare questo in software) ad un solo thread che gestisce 
i dati, e a thread "accessori" che si occupano di gestire grafica, 
protocollo radio ecc.
Nel senso: i thread accessori generano qualche tipo di "segnale" che attiva 
il thread principale (quello che gestisce tutte le strutture dati). Con un 
punto di serializzazione opportuno, e un solo thread che gestisce i dati, 
non avrei bisogno di nessun lock, non ci sarebbe alcuna race condition di 
sorta (cosa che mi fa sentire molto piu' sicuro).
Esempio:
l'utente pigia un tasto -> si genera un "segnale" che attiva il thread 
principale, che aggiunge pacchetti dati alla coda in uscita, comanda 
l'aggiornamento dello schermo ecc., e si rimette a "dormire"
un pacchetto dati arriva -> si genera un altro "segnale" che attiva il 
thread principale che legge il pacchetto, lo parserizza, aggiorna qualche 
struttura dati, notifica un "messaggio in arrivo" all'applicazione, ecc. e 
si rimette a "dormire"
...e cosi' via. Un solo thread gestisce il protocollo, un solo thread 
gestisce l'applicazione, nessuna race condition.
Ha senso una cosa del genere?
Pleg 

 
Secondo me, un sistema real time abbastanza complesso, anche se 
semplificato, va suddiviso in threads.
Non puoi gestire tutto con l'unico thread principale che "a polling" va 
a gestire tutte le varie problematiche di dati seriali, dati da rete, 
grafica, strutture dati, protocolli e via dicendo.
Cioè tutto si può fare, una volta si faceva così, ma l'affare si 
complicherebbe ulteriormente e sarebbe alquanto pessimamente 
ottimizzato, i threads sono stati creati apposta.
Una volta si progettava uno schedulatore software (con un bellissimo 
while (1) che facendo uso di un timer, andava a pescare tutti i 
sottotask adeguatamente memorizzati in una struttura che con periodi di 
tempo diversi, richiedevano l'uso della cpu.
Così avevi:
  il "task" della grafica che una volta al secondo andava ad aggiornare 
le eventuali finestre dati
il "task" delle seriali che ogni decimo di secondo andava a prendere dai 
buffer delle seriali i caratteri arrivati e li andavano a decodificare e 
memorizzare nelle strutture dati
il "task" dei calcoli che ogni secondo prendeva i dati dalle strutture, 
faceva adeguati calcoli e li passava ai dati per la gestione grafica.
ecc...ecc...
Ovviamente questi "task" erano delle funzioni che venivano chiamate 
periodicamente dallo scheduler ad alto livello che non era altro che una 
serie di funzioni per la gestione del sistema.
Tutto questo in un solo unico thread che era poi quello del main().
Adesso ci sono i thread che minimizzano i tempi morti, separano bene i 
compiti ma come contropartita c'è il fatto che bisogna proteggere molto 
bene i dati per evitare inquinamenti fra thread.
Tu mi hai parlato di un solo thread principale che gestisce i dati  e 
altri thread accessori che gestiscono protocolli radio e grafica, quindi 
hai già elencato tre possibili thread che andranno sicuramente a 
condividere dei dati.
I quali dati andranno poi protetti.
Maurus

 
E hai detto niente...
Ciao  Manlio

 suoi reactor, anche GTK e Qt), Perl POE.
Ecco, forse e' questo che mi interessa. Hai qualche buon riferimento da 
darmi per studiare il concetto di "programmazione ad eventi"? Sto cercando 
di capire se il framework giusto su cui strutturare il mio programma.
Ma come mai elenchi diversi linguaggi, tranne il C++?
Pleg

 Ovviamente non fai polling a mano, ma usi select/poll/epoll/kqueue/IOCP.
Di queste conosco solo la select, che uso per la parte del programma che si 
occupa dell'interfaccia seriale (quando arriva un pacchetto, la select 
"risveglia" la parte che gestisce il protocollo). Quello che pensavo di fare 
era estendere questo concetto a tutto il resto del programma - ma non so 
come (come fa una funzione o un oggetto a lanciare un "segnale" che risvegli 
un altra parte del codice?).
Pleg 

 
Boost.Asio è C++. ("AIO" è un refuso.)
 
http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio.html
In alternativa: ACE (
http://www.cse.wustl.edu/~schmidt/ACE-overview.html
).
Max

 
Il flusso del codice in un programma a eventi è molto diverso dal flusso 
di un programma normale.
Dovrai prenderci la mano.
In ogni caso il consiglio è usare un framework di alto livello.
Comunque in un programma a eventi, le varie azioni vengono attivate da 
eventi esterni, ad esempio dati disponibili nella seriale.
Ad un evento puoi associare una callback.
Di solito poi, puoi creare tu stesso degli eventi, come un timer, ad 
esempio.
Ma per i dettagli, dipende da cosa devi fare esattamente.
Ciao

 esempio.
E' un concetto simile a questo
http://doc.trolltech.com/4.5/signalsandslots.html
?
Pleg 



Si.
Con le Qt puoi programmare ad eventi, e probabilmente se ti serve 
comunque una GUI le Qt sono la scelta migliore.
Le Qt supportano la programmazione di rete, mi sembra ci sia supporto 
anche per la seriale, ed infine hai a disposizione una API flessibile per 
gestire un pool di threads.
Personalmente frameworks di questo tipo, in cui "faccio tutto io, 
reinventando il mondo intero" non mi piaccono (ed è una delle ragioni per 
cui mi sono allontanato dal C++, anni fa), ed inoltre le Qt non sono 
proprio sviluppate nel miglior C++, ma almeno funziona
(e bene, sembra - io non le ho mai usate).
Ciao

 comunque una GUI le Qt sono la scelta migliore.
E' quel che pensavo. Non avendo esperienza di nulla, e volendo sperimentare 
anche a fare una GUI, penso che le Qt possano essere una buona scelta.
Un dubbio generale: mi sembra che il sistema di segnali e slot colleghi solo 
oggetti - significa che, in generale, il programma avra' un main() che 
semplicemente dichiara gli oggetti e le connessioni, e _tutto_ il 
funzionamento del programma deve essere contenuto all'interno di qualche 
oggetto?
Grazie per le info e la pazienza :)
Pleg
PS: se studiassi le Qt, quale sarebbe il ng giusto a cui chiedere aiuto? 

 (e bene, sembra - io non le ho mai usate).
Non ci sono le sole QT. Personalmente quando sviluppo un'interfaccia 
grafica la mia scelta e` GTK, e mi sono sempre trovato bene. Ho scritto 
anche applicazioni MOLTO complesse e con requisiti sull'estetica e la 
funzionalita` dell'interfaccia molto particolari.
Come QT anche GTK usa i widget nativi su windows con l'apposito tema e 
le versioni recenti sono disponibili anche per OSX.
Come QT anche GTK si programma a eventi, ma GTK ha un'enorme vantaggio 
su QT: il fatto di non richiedere un passo di precompilazione.
Al contrario di QT con GTK non sei costretto ad utilizzare un framework 
"stl-like" proprietario, l'API nativa di GTK e` in C, ma usabilissima e 
comoda anche in C++.
Esiste un'interfaccia c++ a GTK ufficiale (gtkmm) che si appoggia 
comunque all'STL per gli oggetti base (containers, stringhe...).
Unica cosa in cui indubbiamente QT e` superiore: la documentazione.
Se uno proviene da MFC pero` (anche se non mi sembra il caso dell'OP), 
non consiglierei ne QT ne GTK, ma wxWidgets.
--
Bye,
  Gabry

 su QT: il fatto di non richiedere un passo di precompilazione.
Sono un "poco esperto" anche io ma seguo la discussione con interesse.
Questo punto non mi e' chiaro qualcuno puo' spiegarlo?

> Unica cosa in cui indubbiamente QT e` superiore: la documentazione.
E' fondamentalmente _il_ punto per cui ho scelto di studiare Qt (e vedere se 
fanno al caso mio): partendo da zero, una documentazione estesa e 
particolareggiata mi e' assolutamente necessaria.
Pleg 

nomegenerico ha scritto:

Le QT hanno aggiunto delle estensioni al linguaggio C++ (in particolare 
mi pare ci siano dei "plug" e dei "socket" nelle definizioni delle 
classi). Queste estensioni vengono convertite in C++ "standard" tramite 
un precompilatore.
E.

 un precompilatore.
Grazie per la precisazione, anche se mi sfugge ugualmente il concetto:
precompilatore != preprocessore giusto?
Cioe' cosa significa aggiungere estensioni al C++ standard?
Se fosse qualcosa di diverso dal solito allora dovrei non
poter compilare un programma scritto con le QT con un
compilatore C++ qualsiasi? (Mancherebbe il precompilatore
"non standard")
E invece posso? E se posso allora come fa a non essere C++ standard?

 E invece posso? E se posso allora come fa a non essere C++ standard?
Non puoi, il sorgente va prima passato al preprocessore di QT (moc), 
quindi al compilatore C++ standard.
Non e` detto che tutti i sorgenti richiedano l'uso di moc, solo quelli 
che contengono le direttive non standard per la gestione di segnali e slot.
Ovviamente trolltech fornisce il preprocessore insieme al resto 
dell'ambiente di sviluppo.
Bye,
  Gabry

Ehi Pleg,
sei lo stesso che mi ha risposto su it.comp.lang.c?
Anche io sto sviluppando una rete di sensori, se ti va di scambiare
qualche idea/opinione contattami,
il mio indirizzo email è in chiaro nel messaggio.
Franco

 che contengono le direttive non standard per la gestione di segnali e slot.
Azz...
Ci sara' forse il modo di recuperare il codice standard
generato dal precompilatore delle QT anche se
la cosa non mi sembra simpaticissima.
Molte grazie della risposta!
Ciao.