Newsgroup: it.comp.programmare.win32
Titolo: [eventi, funzioni e messaggi] - quando e come discriminare?

Ciao a tutti, mi piacerebbe sentire qualche opinione in merito all'utilizzo
dei messaggi di Win32 al posto di eventi e/o procedure, attualmente uso
Delphi ma la questione non e' particolarmente legata a nessun linguaggio,
solo all'ambiente Win32...
Tralasciando per un attimo i casi in cui sia NECESSARIO usare messaggi quali
WM_COPYDATA, facciamo un esempio piccolo piccolo...
Ho due oggetti di tipo Window (con il loro bell'Handle, in Delphi sono tutti
i discendenti di TWinControl), facciamo WinA e WinB...
ora WinA cambia di stato e vuole avvisare WinB di questo cambiamento, io
vedo due strade:
1) invio un messaggio
DA WinA...
SendMessage(WinB.Handle, MyMsg_WinAChanged, 0, 0);
magari con MyMsg_WinAChanged = WM_USER + 100;
2) richiamo un metodo dell'oggetto
Da WinA...
m_WinBptr->Update()
-----------------------------------
spedire messaggi e' piu', meno o ugualmente pesante, a livello
computazionale o di impiego di risorse, che richiamare metodi?
Sono SEMPRE sicuro che Win32 recapiti i messaggi? anche in caso di sistema
sovraccarico?
Riesco a rendere l'idea? Non mi sto preoccupando del fatto che con i
messaggi posso passare solo wparam ed lparam, o del fatto che per richiamare
un metodo devo avere un puntatore, mi interessa capire se quella dei
messaggi, spediti e ricevuti, e' una buona scelta architetturale...
ok?... qualcosa mi dice che sono stato poco chiaro... :-(
Grazie per l'attenzione, ne parliamo?
ciao, buon lavoro, Davide.
/ - / - / - | - \ - \ - \
Davide Piras
pir...@engineer.com
\ - \ - \ - | - / - / - /

 messaggi, spediti e ricevuti, e' una buona scelta architetturale...
E` piuttosto valida, per la possibilita` di sfruttare i vari gradi di
decoupling (finestre gestite da thread o processi diversi, coda di
messaggi usabile via post, ...), di garantire piu` agevolmente
contro rientranze indesiderate (chi riceve un messaggio puo`
usare InSendMessage e simili per cautelarsi), eccetera.
Alex

 Si`.
ma i messaggi non vengono messi in coda?
 Che tipo di code usa l'architettura Win32?
ok, immagino siano FIFO ma il buffer e' infinito?
se io invio un messaggio ad una window che deve processarne altri 700 (ad
esempio!), chi mi garantisce che quel messaggio venga processato, piuttosto
che gettato in quanto la coda aveva 699 (esempio) posti?
SendMessage attende che il msg venga processato, postmessage invece no
vero...
grazie mille, ciao, Davide.

 vero...
Fra processi (o thread) diversi, e` piu` o meno cosi`.  Entro lo stesso
processo (sicuramente entro lo stesso thread, ma anche fra thread
diversi se non entrano in gioco problemi di processor-affinity, strane
priorita`, e simili) piu` che di "attendere" si tratta di "diventare a tutti
gli effetti una chiamata" poiche` il flusso di esecuzione procede
direttamente con la window procedure opportuna.
Alex

 direttamente con la window procedure opportuna.
accidenti hai proprio ragione, e pensare che la cosa e' evidente a
debug-time...
ciao, Davide.

Fra processi (o thread) diversi, e` piu` o meno cosi`.  Entro lo stesso
SendMessage puo' ritornare anche a causa di un ReplyMessage, non appena sia
noto il valore di ritorno (c'e' qualche controindicazione nel farlo?).
Saluti,
    Mardy

 wrote in message
G6Qy4.18287$O3.2...@news.infostrada.it...

L'unico rischio che mi viene in mente e` che questo puo` far
si` che si trovino a girare contemporaneamente due thread
che non dovrebbero sovrapporsi; ma se si e` fatto corretto
uso delle strutture di sincronizzazione del kernel, non ci
dovrebbero essere problemi simili.
Alex

 ok, immagino siano FIFO ma il buffer e' infinito?
Mi auguro che, anche nel caso che il buffer non sia infinito, la
PostMessage() restituisca un errore nel caso che non riesca (per
qualunque motivo) a depositare il messaggio nella coda... cosi` a
braccio direi che nel momento in cui PostMessage() restituisce TRUE, tu
possa avere la certezza perlomeno che il messaggio sia stato messo nella
coda (il fatto che poi venga processato e` tutto un altro discorso).
BTW, io da un po' di tempo quando devo spedire delle semplici notifiche
(senza scambio di dati) mi sono abituato a usare gli eventi di Windows
(CreateEvent() e amici). Sono pratici, semplici e funzionano anche fra
processi diversi.
---
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/

 processi diversi.
Domanda da novellino:
Metti un thread in attesa di un evento specifico? [rapporto 1 a 1?]
Così non ti servono troppi thread o usi la WaitForMultipleObjects con un
thread unico?
Non è + semplice e meno dispendiosa una PostMessage?
Ciao :-)
--
(¯`·.¸¸.·´¯`·.¸¸.-> Andrea <-.¸¸.·´¯`·.¸¸.·´¯)
AntiSpam: rimuovere il trattino basso dall'indirizzo per rispondere
AntiSpam: remove the underscore from the e-mail address to reply

 Non è + semplice e meno dispendiosa una PostMessage?
Per quanto riguarda il "piu` semplice", direi che le due alternative si
equivalgano, una volta che si e` pratici dell'utilizzo dei thread (che
mi sono molto simpatici: quando posso ne creo sempre in quantita`, forse
perche` inconsciamente aspiro a un sistema SMP ;-)). Dopotutto per
creare un thread, come pure per "intercettare" la segnalazione di un
evento, e` sufficiente una singola chiamata; paradossalmente serve meno
codice che a gestire una PostMessage (in linea di principio; poi in
realta` usare piu` thread puo` comprtare qualche complicazione anche non
tanto banale, ma questo e` un altro discorso).
Per quanto riguarda il "meno dispendioso", direi proprio di no! La
gestione con eventi e thread separati e` meno dispendiosa e piu`
"performante". Meno dispendiosa, perche` la WaitForSingleObject()
sospende il thread e non consuma assolutamente CPU [1]; piu`
performante, perche` l'evento viene notificato quasi all'istante (giusto
il tempo per "switchare" al thread giusto) mentre con la PostMessage()
puo` esserci una certa latenza. Ci sarebbe la strada intermedia, quella
di usare una SendMessage(), ma in quel caso la chiamata sarebbe sincrona
e quindi potrebbe interrompere per troppo tempo il processo chiamante;
per evitare questa attesa dovremmo creare nel processo chiamato un nuovo
thread che gestisca il messaggio, ma allora saremmo al punto di
partenza. ;-)
[1] Beh, mi immagino che internamente anche la GetMessage() faccia
cosi`. Comunque c'e` sempre un minimo overhead di gestione in piu`.


 "performante".
Pensavo che visto che cmq la coda messaggi viene servita già era meno
dispendioso aggiungere uno switch lì piuttosto che affiancare un thread...
Grazie per le delucidazioni !


Quello che mi chiedo č: avere 50 thread aperti č male?
Urgh!!! 50 !!! secondo me il sistema si inchioppa!!! ;)

 forte, piu` stretto.
bene, ci ho lavorato un poco ma ora e' tutto a posto...
Ho riprogettato parte della mia applicazuone, ora i vari oggetti si
scambiano messaggi, non richiamano metodi altrui...
Non ho bisogno di sapere di che tipo e' un oggetto, se ne conosco l'Handle,
gli invio un messaggio e LUI fa quello che deve fare, ho ridotto
notevolmente l'accoppiamento!
Una domanda:
All'interno dello stesso processo (per ora ho anche un solo Thread ma no e'
detto le cose rimangano cosi'), i puntatori sono validi, dunque posso
inviare un messaggio con, "celato" in Wparam, ad esempio, un puntatore ad un
oggetto: chi riceve il messaggio legge il wparam ed opera sull'oggetto
puntato, mi sembra abbastanza chiaro...
Ma se passo ad un oggetto un puntatore ad un membro privato di un altro
oggetto?
Faro' delle prove, ma mi interessa la vostra opinione...
grazie per pazienza/attenzione/interessamento, cordialmente, Davide.

 oggetto?
Naturalmente funziona, esattamente come funzionerebbe se
quel puntatore tu lo passassi ad un metodo: cioe`, il chiamante
deve avere l'accessibilita`, ma, avendola, puo` passare il
puntatore a chiunque altro per l'uso desiderato.
Alex

 pesante di una gestione in coda?
Di fatto anche i thread in attesa sono posti in una coda, gestita
direttamente dallo scheduler (e quindi in linea teorica piu` efficiente
di una normale coda dei messaggi che gira in user mode).
