Newsgroup: it.comp.lang.perl
Titolo: problemi con while,socket e alarma()

Cosi' facendo e sorta un'altra complicazione...
Il codice sottostante non si comporta come dovrebbe!
si mette in ascolto e ogni 10 secs dovrebbe eseguire "temporizzata",
ma invece dopo i primi 10 secs mi esegue "temporizzata" ma poi lo script 
non sta
piů in ascolto...roba da matti!
[code]
$socket->listen();
$SIG{'ALRM'} = \&temporizzata;
alarm(10);
while ( $client = $socket->accept() )
{
   while ( $str = <$client> ) { syswrite $client, uc($str) . "\r\n"; }
}
sub temporizzata
{
  my $dataora = gmtime(time());
  print "\n",$dataora,"\n";
  $SIG{'ALRM'} = \&temporizzata;
  alarm(10);
}
[/code]
alcontrario ho notato che se faccio un ciclo while(1) tutto va a 
meraviglia:
[code]
$SIG{'ALRM'} = \&temporizzata;
alarm(10);
while (1) {}
sub temporizzata
{
  my $dataora = gmtime(time());
  print "\n",$dataora,"\n";
  $SIG{'ALRM'} = \&temporizzata;
  alarm(10);
}
[/code]
ogni 10 secs mi esegue "temporizzata" !!!
ne consegue che io ho provato a fare questo:
[code]
$socket->listen();
$SIG{'ALRM'} = \&temporizzata;
alarm(10);
while (1)
{
    $client = $socket->accept();
 
    if ($client) {
      while ( $str = <$client> ) { syswrite $client, uc($str) . "\r\n"; }
    }
 
}
sub temporizzata
{
  my $dataora = gmtime(time());
  print "\n",$dataora,"\n";
  $SIG{'ALRM'} = \&temporizzata;
  alarm(10);
}
[/code]
... e devo dire che funziona,ma non vorrei che i puristi del perl 
storcessero il naso,ovvero
che differenza c'č nel prepararsi a ricevere un client con:
[code]
while ( $client = $socket->accept() ) { #code... }
[/code]
e
[code]
while(1) { $client = $socket->accept(); # other code... }
[/code]
Grazie a tutti!

 meraviglia:
E' proprio cosi', come ti ho risposto nell' altro thread.
while(1) va bene, il processo si ferma sempre e comunque su
accept() e dopo accept() fai il test della validita' del
nuovo socket.
P.S.
Puristi del perl? Ce ne sono? E fanno pure gli schizzinosi?
Mai visti. Altrimenti i Pythonisti cosa sono allora?? :)
Ciao.
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 si rientrera' nel punto abbandonato. 
quindi che questo sia il codice perfetto?
[code]
$socket->listen();
$SIG{'ALRM'} = \&temporizzata;
alarm(10);
while (1)
{
    $client = $socket->accept();
 
    if ($client) {
      $SIG{'ALRM'} = 'DEFAULT';
      while ( $str = <$client> ) { syswrite $client, uc($str) . "\r\n"; }
      close $client;
      $SIG{'ALRM'} = \&temporizzata;
      alarm(10);
    }
 
}
sub temporizzata
{
  my $dataora = gmtime(time());
  print "\n",$dataora,"\n";
  $SIG{'ALRM'} = \&temporizzata;
  alarm(10);
}
[/code]
il tempo di esesecuzione di "temporizzata" non credo che supererà i 5 
secs...e cmq nel mio stretto caso alarm sarà settato a 30 * 60 (30 min)
Grazie ancora!!!!!

 nuovo socket.
una domanda:
ma con while(1) non aumento le prestazione del sistema rispetto a 
while($socket->accept()) ? (te lo chiedo)
un'altra domanda:
se uso while(1) più il codice che di cui già abbiamo parlato dentro le 
{} ,quando il socket riceve una chiamata e la accetta, continuera ogni 
10 secs a eseguire "temporizzata" oppune aspetta che sia chiusa la 
comunicazione con il client?
Grazie mille!!!!

 Grazie mille!!!!
Se non metti l' handler di SIGALARM a 'DEFAULT' o a 'IGNORE' in qualche
punto del programma, continuera' ad essere inesorabilmente eseguita in
modo del tutto ASINCRONO rispetto al flusso del programma. praticamente
si abbandonera' l' esecuzione, si eseguira' handler &temporizzata() e
si rientrera' nel punto abbandonato. Una eccezione:
Se l' handler e' lungo da eseguire, un' altra occorrenza di SIGALARM
verra' "ricordata" (BSD docet) per eseguire ancora handler dopo che
questo sara' terminato. (praticamente un handler di gestione di un signal
NON PUO' essere interrotto dallo stesso signal)
Quindi se &temporizzata() eseguira' calcoli per piu' di 10 secondi
NON VERRA INTERROTTA da alarm() (in questo caso non potrebbe comunque
succedere perche e' l' handler stesso che riarma alarm(), ma generalizzando
sui signal(), l' handler in esecuzione BLOCCA il signal() che verra'
comunque ricordato al suo termine come se fosse arrivato piu' tardi.
Il signal non sono una cuccagna per tutto, pero' aiutano, bisogna saperli
scegliere la momento giusto eprogettare bene il codice.)
ciao


 Grazie mille!!!!
Se non metti l' handler di SIGALARM a 'DEFAULT' o a 'IGNORE' in qualche
punto del programma, continuera' ad essere inesorabilmente eseguita in
modo del tutto ASINCRONO rispetto al flusso del programma. praticamente
si abbandonera' l' esecuzione, si eseguira' handler &temporizzata() e
si rientrera' nel punto abbandonato. Una eccezione:
Se l' handler e' lungo da eseguire, un' altra occorrenza di SIGALARM
verra' "ricordata" (BSD docet) per eseguire ancora handler dopo che
questo sara' terminato. (praticamente un handler di gestione di un signal
NON PUO' essere interrotto dallo stesso signal)
Quindi se &temporizzata() eseguira' calcoli per piu' di 10 secondi
NON VERRA INTERROTTA da alarm() (in questo caso non potrebbe comunque
succedere perche e' l' handler stesso che riarma alarm(), ma generalizzando
sui signal(), l' handler in esecuzione BLOCCA il signal() che verra'
comunque ricordato al suo termine come se fosse arrivato piu' tardi.
Il signal non sono una cuccagna per tutto, pero' aiutano, bisogna saperli
scegliere la momento giusto eprogettare bene il codice.)
ciao


 [/code]
Mi pare di capire che mentre il server gestisce la connessione con il
client non vuoi che la funzione temporizzata venga eseguita.
in tal caso l' approcio corretto e disarmare alarm con
alarm(0)
che vuol dire "non schedulare allarmi ed elimina precedenti allarmi
schedulati" (ogni volta che scheduli un alarm elimini i precedenti
ma non e' un problema. alarm restituisci il numero di secondi che
mancavano alla scadenza di una eventuale precedente richiesta)
alla chiusura delle connessioni riarmi alarm(10)
l' handler lo puoi lasciare installato. Effettivamente ti ho messo fuori
strada io con il mio messaggio precedente.
Se tu sostituisci l' handler con 'IGNORE' l' allarme schedulato ad un
momento ti mandera' il signal SIGALRM ch pero' verra' "scaricato" come
un colpo a salve e tutto funzionera' comunque.
Se invece metti 'DEFAULT' l' azione di default per SIGALRM e' tirare
il collo al processo.
Ciao
Roberto


,
 
nogr...@noncomproviagra.it
 (Roberto C) wrote:

quindi ne viene fuori che questo è il codice perfetto...
[code]
$socket->listen();
// Accendi la sveglia...
$SIG{'ALRM'} = \&temporizzata;
alarm(10);
while (1)
{
    $client = $socket->accept();
    if ($client) {
      // Sospendi la sveglia...
      $SIG{'ALRM'} = 'DEFAULT';
      alarm(0);
 
      while ( $str = <$client> ) { syswrite $client, uc($str) . "\r\n"; }
      close $client;
 
      // Riaccendi la sveglia...
      $SIG{'ALRM'} = \&temporizzata;
      alarm(10);
    }
 
}
sub temporizzata
{
  my $dataora = gmtime(time());
  print "\n",$dataora,"\n";
  $SIG{'ALRM'} = \&temporizzata;
  alarm(10);
}
[/code]
questa del $SIG{'ALRM'} + alarm() era una cosa che mi mancava in Perl!!!!
Grazie mille!


