Re: Using signals in Perl
by kal (Hermit) on Mar 28, 2001 at 20:17 UTC
|
One method is to keep pipes open to the children - if you have a pipe which the parent reads and the child writes, you can send your dots (valid progess indicators :) down the pipe. You then remove file locking problems (which you have with writing dots to a file). You end up with a parent with a whole bunch of pipes - just do a select() on these, and you'll get woken up whenever there's anything to read from them.
Pipes were pretty much invented for this - they survive fork (i.e., both child and parent can still see it!). Pipes rock :) Programming Perl has some other good examples of IPC - shared memory, sockets, etc., but all that's a bit overboard for what you want. The usual pipe way is:
pipe(READHANDLE, WRITEHANDLE);
my $result = fork();
if ($result>0) {
# child process, we write to the pipe
} else {
# parent process, or error - might want to check before
# we try to read from pipe :))
}
If you want more than one child, just keep the handles in an array so you don't lose them, and do a select() in the parent when all the children are active.
Oh, and beware of buffering - probably best to turn that off when debugging :)
| [reply] [d/l] |
Re: Using signals in Perl
by mikfire (Deacon) on Mar 28, 2001 at 20:15 UTC
|
Ouch. Those signals are gonna hurt. You have wandered hard
into a great example of why you should avoid signals in
perl if possible. Basically, you were handling a signal
when another signal arrived and went of to handle the second
signal. Signals are not re-entrant, which means the first
signal was dropped on the floor and escaped into the ether.
How about using the open call which forks a child and attaches
the child's STDOUT to a file handle? From there, it is a
matter of having the children printing to STDOUT and
the parent using select() to check for waiting input.
See perldoc perlipc under the "Safe Pipe Opens" section for
the syntax a a discussion of how to use the open() call
effectively.
mikfire | [reply] |
Re: Using signals in Perl
by merlyn (Sage) on Mar 28, 2001 at 20:48 UTC
|
You might never see as many signals as you have events, because signals are a "1-bit" message.
If a second signal arrives before the first one has started to be handled, the kernel just goes
"yeah yeah, I'm already gonna send him one of those!" and discards it.
By the way, this is the complaint I have with that bad child-reaper meme
that uses a wait inside a SIGCHLD handler. Multiple SIGCHLDs will
be stacked as one, and therefore some kids will be missed and zombified at random.
-- Randal L. Schwartz, Perl hacker | [reply] |
Re: Using signals in Perl
by physi (Friar) on Mar 28, 2001 at 20:21 UTC
|
Hi,
I've got a quick look in the Cookbook.
There is a Module IPC::Shareable, which allows you
to share a variable between many processes. Maybe this help's.
Or another idea is that your childprocesses do not send a SIGNAL after
every mail send, but after 10,20,30. So your Parent process got
not that much Signals. But normaly I would say, that the SIGUSR2 - Methode
should work.
A third way might be to open your childs with pipe.
like:
use IO::Handle;
if ($pid = open(CHILD1, "-|")) {
here you can read fom STDIN that what your child will tell you,
but I don't know if this methode works with multiple childs.
}
-----------------------------------
--the good, the bad and the physi--
-----------------------------------
| [reply] [d/l] |
Re (tilly) 1: Using signals in Perl
by tilly (Archbishop) on Mar 28, 2001 at 21:56 UTC
|
I wouldn't use signals with Perl. Tell whoever gave you
that advice that you have it from a reliable source - ie
some stranger on a website - that signals in Perl are not
reliable.
But if you only need to know when the kids died, just pollwaitpid periodically to find out if any more kids exited. | [reply] |
Re: Using signals in Perl
by Albannach (Monsignor) on Mar 28, 2001 at 20:15 UTC
|
Just a couple of ideas off the top of my head as I've not done this type of thing:
- instead of a signal for every message, send one for every 10th or some
pre-set number. Better would be to get each child to signal on every
10% complete of whatever their task was. This would still cause problems
if their tasks were very small though, and it certainly wouldn't ensure that
no signals were lost.
- Try a whole different approach using IPC::Shareable, and have a look at this thread which may help.
--
I'd like to be able to assign to an luser | [reply] |
Re: Using signals in Perl
by suaveant (Parson) on Mar 28, 2001 at 20:09 UTC
|
A suggestion for your old way, which isn't terrible,
instead of having the parent read the file, just use -s
to read the size of the file. Each . is one byte, should
be quicker than opening and reading the file.
- Ant | [reply] |
Re: Using signals in Perl
by ChOas (Curate) on Mar 29, 2001 at 13:50 UTC
|
Hey!
Just a quick one: I think you could do this easily, using Semaphores,
I mean.. I think they would be great at this job...
Check out IPC::Semaphore
GreetZ!,
print "profeth still\n" if /bird|devil/; | [reply] |