Newsgroup: it.comp.lang.perl
Titolo: comandi temporizzati

prima di mettermi a scribacchiare in perl, ero solito ingannare parte del 
mio tempo realizzando script per Mirc il quale tra i millemila comandi e 
funzioni ne ha una la cui sintassi è questa:
 
/timer[N/name] [-cdeomhipr] [time] <repetitions> <interval> <command>
Activates the specified timer to perform the specified command at a 
specified interval, and optionally at a specified time.
 
in pratica il comando /timer_prova 5 10 un_qualsiasi_comando esegue 
"un_qualsiasi_comando" 5 volte con un intervallo di 10 secondi e poi 
termina. In realtà può fare molto altro, tipo eseguire un comando ad una 
data ora,  ma in questo momento a me basterebbe poter fare in perl una cosa 
tra "x" tempo.
 
una cosa tipo questa:
 
sub fai_qualcosa_tra_1_minuto {
sleep 60;
	print "ho fatto qualcosa. \r\n";
}
...
&fai_qualcosa_tra_1_minuto()
...
...
print "questi altri comandi devono attendere lo scadere del tempo... \r\n";
...
...
 
funziona, ma lo script non fà altro fino alla scadenza del tempo, e lo 
script resta inerte fino allo scadere del tempo.
Qualche idea?
 
 
 
-- 
Fri(END), Boyfri(END), Girlfri(END), Bestfri(END). Everything has an END 
except...Fam(ILY)! It Has 3 Letters that say I LOVE YOU 
 

Magari ho capito male ma credo tu debba forkare il processo e attendere 
la fine del figlio che ti interessa prima di poter fare altro.
Ripeto magari ho capito male io il problema

 Ripeto magari ho capito male io il problema
 
quello che vorrei fare io è più o meno:
 
istruzione 1
istruzione 2
---------->istruzione3 da fare tra 60 secondi (o comunque un tempo 
definibile)
istruzione 4 (senza aspettare che istruzione 3 sia stata eseguita)
istruzione 5
ecc. ecc.
 
il resto dello script è un irc bot che dovrebbe fare da "portiere" e 
lasciare libero accesso solo a chi ne ha l'autorizzazione. L'utente non 
autorizzato viene "bannato", ma per un tempo limitato.
 
questa è la parte di codice:
 
 if ($answer  =~ /\:(.*)!.+?(JOIN)\s:($chan)/) {
                $temp = $1;
                 if (grep(/^$temp/i,@database)) {
                        print $server "PRIVMSG $chan : Benvenuto su $chan 
$temp \r\n";
                }
                else {
                        print $server "PRIVMSG $chan : $temp non presente 
nel database \r\n";
				print $server "MODE $chan +b $1 \r\n";
				print $server "KICK $chan $1 Questo e' un chan PRIVATO, contatta un 
operatore!\r\n";
                                                                &unban($temp);
                }
        }
 
chiaramente se &unban() mi tiene fermo lo script per N secondi, e nel 
frattempo entrano 3 user, il 3° viene bannato solo dopo 3 x 
il_tempo_di_unban, e non è proprio il massimo :-)


Così al volo mi viene da confermarti l'uso di programmazione di sistema 
e nello specifico una fork... Con magari l'aggiunta di qualche variabile 
di memoria condivisa.
 
Perdonami se son poco propositivo ma in questi giorni sono un po' "cotto"

 perl una cosa tra "x" tempo.
 
In ambiente *nix c'e' il comando at (non scomoderei cron, buono comunque
anche lui) che fa questo ed altro. Credo che il comando at o qualcosa
di simile esista anche in windows (mi pare di capire che questo e' il
SO in cui operi); perl puo' essere utile in certi casi per lanciare at
o quel che e' tramite system o simili, tra l'altro per "tradurre" i
parametri dal formato a te piu' congeniale a quello del comando...
 
-- 
220284
 

 memoria condivisa.
 
purtroppo questo per me è arabo... le mie capacità "programmatorie" sono 
limitate.


 parametri dal formato a te piu' congeniale a quello del comando...
 
Niente windows, o meglio io uso windows ma il "target" dello script dovrebbe 
essere una macchina linux.
Ad ogni modo at farebbe quello che mi serve, ma essendo at (e lo stesso vale 
per cron**) una cosa esterna, come posso farlo interagire con il mio script? 
Io non devo ricevere un risultato, ma devo "scrivere" su un server irc un 
comando e questo cron o at non possono certo farlo. O no?
 
** cron non l'ho mai usato, ma nel mio caso non ho un orario prefissato in 
cui eseguire un compito, ma il compito stesso è generato sul momento cioè:
 
(si parla sempre di un bot irc)
 
un user entra in un canale
il bot controlla se è presente nel database degli autorizzati
se non è presente l'user viene bannato per un minuto
 
Usare sleep 60 mi ferma tutto, quindi se per colmo di sfiga entrano 10 user 
assieme, e tutti e 10 non fossero autorizzati, l'ultimo verrebbe bannato 
dopo 10 minuti, e questo non è il massimo.



devi usare i thread oppure fare dei fork per ogni utente
E' il classico problema del server che resta in ascolto e quando arriva 
la richiesta la delega ad un figlio (processo o thread)
 

 richiesta la delega ad un figlio (processo o thread)
 
ho trovato un paio di link che oggi proverò a comprendere:
 
per i threads: 
http://www.cattlegrid.info/blog/2006/04/threading-in-perl.html
 (l'unico per 
ora in italiano...)
 
per i (o la?) fork non ci ho capito molto, anche perchè quel poco che ho 
trovato (rigorosamente in inglese) parte dall'assunto che chi legge sappia 
perfettamente cosa sta leggendo... ho trovato comunque questo:
 
#!/usr/local/bin/perl
use strict;
my $pid;
die "cant fork $!\n" unless defined($pid=fork());
 if($pid) {
 print "I'll do what i want here\n";
 my $in=<STDIN>;
   while ($in ne 'stop') {
   $in=<STDIN>;
   chomp $in;
   print "$in is your input\n";
       if($in eq 'stop') {
       print "exiting.........\n";
       }
   }
 }
 else {
LOOP1:
  sleep 10;
  print "im printing this cause my timer just went off\n";
goto LOOP1;
 
 }
print "you can say bye bye now or \n";
print "do something else here before you go\n";
kill ("TERM",$pid); # not that graceful of an exit though :D
 
che pare fare quello che serve a me e così com'è funziona, solo non sono 
ancora riuscito ad implementarlo nel mio codice.
Mi apsetta una giornata di mal di testa :-)



per sapere come funziona fork cerca fork come syscall unix
a parte il valore di ritorno in caso di errore il funzionamento è identico
 

 a parte il valore di ritorno in caso di errore il funzionamento è identico
 
Per il momento credo di aver risolto con i threads, faccio dei test per 
vedere se ci sono dei malfunzionamenti alla distanza, ma voglio approfondire 
l'argomento che mi pare interessante...
 
Per quanto riguarda "fork", farò lo stesso appena ho capito a sufficienza i 
threads, sempre se non mi si fonde il cervello prima :)
Grazie!
