Re: running a loop in background...
by suaveant (Parson) on Sep 10, 2001 at 23:49 UTC
|
You want to fork() that into the background... as such
my $child;
unless($child = fork()) {
open (FH, "$statusfile") or die "Unable to open file: $!";
my $DELAY = 5;
for(;;) {
while(<FH>) {
print;
}
sleep $DELAY;
seek(FH, 0, 1);
}
}
# continue with main program
kill(15, $child); #when you want it to stop
Update wog reminded me kill needed a signal passed!
- Ant
- Some of my best work - Fish Dinner
| [reply] [d/l] |
|
|
This may be a problem that you cannot solve, but after
using that code, Dr. Watson strikes. Why am I still using
NT? okay that's beside the point. Any ideas on why this would happen?
| [reply] |
|
|
From perldoc perlfork:
On some platforms such as Windows where the fork() system call is not available, Perl can be built to emulate fork() at the interpreter level. While the emulation is designed to be as compatible as possible with the real fork() at the level of the Perl program, there are certain important differences that stem from the fact that all the pseudo child ``processes'' created this way live in the same real process as far as the operating system is concerned.
In short, YMMV. Make sure you have the latest perl ( >= 5.6.0 ) from ActiveState or whomever built your distribution.
HTH
--
idnopheq
Apply yourself to new problems without preparation, develop confidence in your ability to to meet situations as they arrise.
| [reply] |
|
|
| [reply] |
|
|
I have no idea what you can do, except create another script to do this and create a backgrounded win32 process... which I don't know how to do, but can be done... you could also just
read a few lines from the log in your idle time...
for(;;) {
do tcl stuff...
seek
read
print
}
- Ant
- Some of my best work - Fish Dinner
| [reply] [d/l] |
Re: running a loop in background...
by kschwab (Vicar) on Sep 11, 2001 at 01:19 UTC
|
fork() is problematic with Tk applications, as the child
process can't munge with the parent's window hierarchy. You could fork(), and then have the child feed the data over a pipe or socketpair...seems complicated though.
There is Tk::fileevent, which gets you most of the way there, but
doesn't have a built-in mechanism to re-seek for the 'tail -f' functionality you need. Basically the fileevent fires on eof, so you would have to turn the fileevent on and off. Ick.
My last idea was to use Tk::After's repeat() functionality. Seems to work for me. This short example creates a listbox, and does something of a "tail -f /tmp/testfile" on it while still allowing other events to fire. (You can type in the entry box to verify this)
Here you go:
#!/usr/bin/perl
use IO::File;
use IO::Select;
use Tk;
my $FILE=IO::File->new("/tmp/testfile") or die;
my $SEL=IO::Select->new();
$SEL->add($FILE);
my $mw=Tk::MainWindow->new();
my $list=$mw->Listbox->pack();
my $entry=$mw->Entry->pack();
$list->repeat(500, sub {
if ($SEL->can_read(0)) {
while(<$FILE>) {
chomp;
$list->insert(end,$_);
$list->see(($list->size)-1);
}
seek(FILE,0,1);
}
});
MainLoop;
Update: Depending on how fast the text is
streaming, you may want to call Tk::DoOneEvent(0)
in the while(<$FILE>) loop. | [reply] [d/l] |
(dws)Re: running a loop in background...
by dws (Chancellor) on Sep 11, 2001 at 00:21 UTC
|
The MisterHouse Perl-based X-10 home automation inverts this problem. Rather than running a loop in the background, they service Tk in the foreground loop. If I recall correctly, they use the 4 argument form of select(), which might induce a bit of typing lag.
The MisterHouse code base is fascinating (and occassionally horrifying) to spend time in. Within one big outer loop, it services X10, Tk, a Web Server, and a bunch of statically and dynamically scheduled tasks.
| [reply] [d/l] |
Re: running a loop in background...
by John M. Dlugosz (Monsignor) on Sep 11, 2001 at 00:11 UTC
|
Tk has an idle function you can use. I don't remember what it's called. | [reply] |
Re: running a loop in background...
by Chmrr (Vicar) on Sep 11, 2001 at 04:17 UTC
|
You need to give Tk the opportunity to deal with updating windows and responding to events. Stick in one or more $MainWindow->Update; inside the various loops. Of course, your MainWindow object may not be named $MainWindow, but you get the idea. You might also want to look into $MainWindow->IdleTasks; which just deals with callsbacks. Both of the above are described in the Tk::Widget POD.
perl -e 'print "I love $^X$\"$]!$/"#$&V"+@( NO CARRIER'
| [reply] [d/l] [select] |
|
|
$mw->update did the trick.....Thanks a lot. but now,
of course another problem arises. When the updated file
is finally complete, how do I stop 'seek'ing? I tried:
for(;;) {
while(<FH>) {
$textbox->insert('end', $_);
$textbox->yviewScroll(1, "units");
#print substr($_,0,5);
$test = $_;
if (substr($_,0,5) eq "\>info") {last;}
}
#sleep $DELAY;
$mw->update;
if (substr($test,0,5) ne "\>info") {
seek(FH, 0, 1);}
}
}
The 'last' function doesn't seem to work. It should be
easy, but being new to perl, I'm having trouble.
Can anyone help? | [reply] [d/l] |
|
|
Your problem boils down to the following: You have two loops, and you need to exit both of them from the innermost one. There are multiple ways of doing this (need I say that, with Perl?)
- Label the outermost loop:
OUTER: for (;;) {
while (<FH>) {
# stuff
last OUTER if substr($_,0,5) eq "\>info";
}
# stuff
}
- Use a flag to tell the outer loop we're done:
for (my $done = 0; !$done;) {
while (<FH>) {
# stuff
++$done && last if substr($_,0,5) eq "\>info";
}
# stuff
}
By the way, watch the capitalization on the methods. I'm not certain if $mw->update will work; I'm more certain $mw->Update will.
perl -e 'print "I love $^X$\"$]!$/"#$&V"+@( NO CARRIER'
| [reply] [d/l] [select] |