Newsgroup: it.comp.lang.c
Titolo: sbloccare select con timeout

Salve a tutti.
Sono quasi sicuro di non essere sul NG appropriato, di conseguenza 
chiedo scusa in anticipo.
Purtroppo non so a chi altro chiedere...
Ho un worker thread normalmente bloccato su una select con timeout.
Tale select ascolta i messaggi TCP in arrivo su una certa socket.
La select non ha timeout infinito semplicemente perche` il worker 
thread deve anche controllare l'arrivo di messaggi da una coda interna 
di eventi generati da altri thread. Per questo motivo il worker thread 
e` costretto ad effettuare un polling, che desidererei eliminare.
Vorrei sapere se esiste un modo qualunque ma efficiente (anche con 
Windows) per sbloccare la select con un 
qualche "segnale"(interruzione), anche eventualmente con l'ausilio di 
una "dummy socket". Questo mi consentirebbe di evitare il polling e 
andare a leggere la coda di eventi interni solo quando necessario.
TENETE PRESENTE CHE NON POSSO:
1)avere un thread separato fermo sulla select ed un semaforo 
condizionale sul worker thread che venga segnalato (sbloccato) 
indifferentemente dal thread fermo sulla select o da un qualunque altro 
thread che generi un messaggio nella coda di eventi. IL MOTIVO E` CHE 
TRATTANDOSI DI UNA SOLUZIONE MODULARE FINIREI PER AVERE DUE THREAD PER 
OGNI MODULO ANZICHE` UNO, E PURTROPPO I MODULI SONO MOLTI.
2)chiudere il "dummy socket" allo scopo di sbloccare la select. MI 
COSTEREBBE TROPPO DOVERLO RICREARE OGNI VOLTA.
Grazie tante a tutti.
Alessio


Non ho capito la domanda. La select(2) ha un parametro per il timeout.
"man 2 select" oppure "
http://www.manpagez.com/man/2/select/
"
Sempre la select(2) è interrompibile da un signal(7).
Dov'è il problema?

 
Ciao,
grazie per la risposta.
La domanda e`: come posso interrompere una select con timeout (prima 
della scadenza del timeout) tramite un qualunque segnale? 
La mia soluzione deve essere portabile, e mi risulta che Windows non 
abbia i segnali (quindi credo di non poter usare la signal). 
C'e` un altro dettaglio: non posso usare Winsock2 ma solo Winsock.
Grazie tante,
Ale

 necessario.
IMO um modo efficiente potrebbe essere quello di trasformare la coda 
in un socket e mettere la select() in attesa su entrambi.  In questo 
modo avresti possibilità di gestire la coda immediatamente all'arrivo 
di ogni messaggio.
Se Windows non gestisce i socket come unix pupoi usare un socket TCP 
aperto su una porta del localhost (127.0.0.1)
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   < 
http://giovanni.homelinux.net/
 >

 Ale
Varie soluzioni:
1- Metti un timeout basso :-)
2- Manda i messaggi su un socket locale.
3- Usa un thread per la select e uno per la coda.
Poi dipende dall'architettura che hai in mente - per ciò che puoi fare
con Windows e le sue chiamate di sistema passo la palla a
qualcun'altro
<nazi>Personalmente direi che la soluzione ottimale sarebbe di lasciar
perdere Windows, che è obsoleto, brutto e cattivo.</nazi>

 Giovanni
Grazie tante.
Potrebbe essere una buona idea.
Peccato che la coda di cui sopra e` una coda con priorita`, e i messaggi 
(gli eventi) hanno potenzialmente priorita` variabile, di conseguenza 
l'ordine di interarrivo che mi offrirebbe una socket TCP non farebbe al 
caso mio.
Inoltre avrei sempre il problema della molteplicita`: dovrei aprire un 
sacco di socket non indispensabili consumando altrettante porte, 
risultando in un consumo di risorse inadeguato alle mie esigenze.
Dunque mi confermi che su Windows che non c'e` verso di interrompere una 
select?
Mannaggia....
Grazie 1000.
Ale

 
Grazie tante per i suggerimenti.
Purtroppo un timeout basso aumenterebbe il problema dell'indesiderata attesa 
attiva. D'altra parte un timeout alto potrebbe farmi ritardare la gestione di 
un evento in coda interna. Al momento ottengo un compromesso con un 
timeout "adattivo": nell'intorno della ricezione di un evento interno il 
timeout e` basso, e va crescendo man mano che gli eventi interni si 
rarefanno, dando priorita` ai messaggi esterni.
Una socket locale non farebbe al caso mio, perche` risulterebbe in un consumo 
eccessivo di risorse, cosi` come l'uso di un altro thread.
Purtroppo avrei proprio bisogno di interrompere la select...
Ti ringrazio molto per esserti interessato al mio problema.
Ale.

 Ale.
Comunque, tanto per chiudere il cerchio, ti faccio una domanda io. Non
capisco dove potrebbe essere lo spreco di risorse che dici.
L'applicazione avrà molti thread ma uno solo con la select, e per le
code di priorità provenienti da un socket basta mantenere una lista.
Cosa dovrebbe fare tutto questo sistema?

 
E` proprio questo il punto.
Si tratta di una libreria per la gestione delle socket con connessione (TCP) o 
senza (UDP). 
Senza entrare nel merito della bonta` della scelta adottata, la modularita` e` 
tale per cui esiste un thread per ogni socket.
Questo thread deve gestire simultaneamente 1) la ricezione di messaggi sulla 
socket, 2) le richieste di send (asincrone bufferizzate) attraverso tale 
socket, 3) le richieste interne di servizio (richieste di disconnessione, di 
turn-off del gestore stesso, ecc..).
Grazie tante.
Ale

 interrompere una select?
Se hai la select() dovresti anche avere la kill() quindi la 
possibilità di gestire i segnali.  Che compilatore e librerie stai 
usando?



Vabè, allora è sbagliata l'astrazione: un socket non è una funzione, è
un "riferimento". Avrebbe (ed ha) molto più senso fare un thread per
ogni *operazione* possibile su più socket, come in effetti fanno molte
altre librerie (quindi un thread per le connessioni in entrata, uno
per gestire i dati in entrata, etc.). I socket sono un'astrazione del
sistema di gestione di rete sottostante. Di certo non sono perfetti,
ma stravolgere il sistema in questo modo è secondo me
controproducente.
E comunque: se ogni thread gestisce un solo socket non ti serve la
select(). La select serve appunto per gestire più file descriptors
contemporaneamente. Fai una read bloccante.

 Giovanni
VC60 (Microsoft Visual Studio 6)
Winsock
Ciao e grazie,
Ale

 
Sono d'accordo con te ma non posso stravolgere la struttura. 
Si tratta di roba esistente e funzionante da anni.
Grazie mille
Ale