Newsgroup: it.comp.lang.perl
Titolo: select unix-switching

ho riscontrato un comportamento anomalo sulla funzione select, usata per 
  selezionare, in un insieme di filehandle, quello che ha subito una 
scrittura.
leggendo la documentazione ho capito che la seguente linea di codice:
     vec ($myset, fileno($fileHandle), 1)=1;
corrisponde alla macro: FD_SET
....e che
     vec ($myset, fileno($fileHandle), 1)
corrisponde alla macro: FD_ISSET
Quindi ho scritto il seguente programma di test:
----------------------------------------------------------------------
#!/usr/bin/perl
use constant FH1        => "/tmp/Perikronos/multiple_debug_console_in.fifo";
use constant FH2        => "/tmp/Perikronos/pipe1";
$n=1;
open ($fh1, "< ".FH1) or die "ERROR! impossible to open the read-only 
channel for Debug Console Service\n";
print ("FH1=$fh1 FD1=".fileno ($fh1)." file=".FH1."\n");
open ($fh2, "< ".FH2) or die "ERROR! impossible to open the read-only 
channel for Debug Console Service\n";
print ("FH2=$fh2 FD2=".fileno ($fh2)." file=".FH2."\n");
while ($answer ne "quit") {
       $myset="";
       vec ($myset, fileno($fh1), 1)=1;
       vec ($myset, fileno($fh2), 1)=1;
       $nfound=0;
       $nfound=select ($myset, undef, undef, 0);
       print "[$nfound]\n";
       if ($nfound) {
             if (vec($myset, fileno($fh1), 1)) {
                   $n=1; $a="";
                   print "FH1: ";
                   while ($a ne "\n" and $n > 0) {
                         $n=sysread ($fh1, $a, 1);
                         if ($n > 0) {print "$a";}
                   }
             }
             if (vec($myset, fileno($fh2), 1)) {
                   $n=1;
                   print "FH2: ";
                   while ($a ne "\n" and $n > 0) {
                         $n=sysread ($fh2, $a, 1);
                         if ($n > 0) {print "$a";}
                   }
             }
       } else {
             print "t! ";
       }
       sleep (1);
}
----------------------------------------------------------------------
Ma, mandando sui due file un carattere (a) ho ottenuto il seguente 
inatteso aoutput:
FH1=GLOB(0x812c788) FD1=3 
file=/tmp/Perikronos/multiple_debug_console_in.fifo
FH2=GLOB(0x812d298) FD2=4 file=/tmp/Perikronos/pipe1
[2]
FH1: a
FH2: [2]
FH1: FH2: a
[2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
FH1: FH2: [2]
Dal quale si conclude che, le operazioni di FD_SET e FD_ISSET funzionano 
correttamente (FH1: a   FH2: a), ma che dopo la read dai due filehandles 
i flag relativi non vengono resettati!
Sono convinto che non si tratti di un bug di Perl, tuttavia non trovo 
soluzioni, qualcuno ha qualche idea??
ringrazio anticipatamente dell'aiuto.
Silvano

 Silvano
select() e' come Furia cavallo del West: difficile da addomesticare.
Ciao
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Ho dimenticato di specificare che un filehandler o sockethandler
quando chiuso da remoto sblocca la select() sia ai tests di read che
di write e continuera' a farlo finche' non chiami close().


Grazie mille Roberto, la tua spiegazione č illuminante, ci sono perň 
ancora un paio di domande che vorrei porti:
1) tu dici che quando nel canale non ci sono piů caratteri, devo 
necessariamente chiudere il filehandle, corretto? ma allora funziona in 
modo radicalmente diverso dalla select in C.
2) se chiudo il filehandle come posso prendere altre stringhe di 
caratteri che mi vengono inviate in un secondo tempo? devo rifare open?? 
ma in questo modo non ottengo delle prestazioni molto ridotte?
3) come mai quando il canale č vuoto, la select, invece di restituire 
errore ([-n]), prosegue convinta che nel canale ci siano ancora dati ([2])?
grazie ancora
Silvano


 Silvano
Ciao
Roberto


Grazie mille Roberto
Ciao
Silvano
