The point is that the clients stay permanently connected, and reconnect if the connection is dropped. The server is POS server and the clients are Tills working with the POS server. There is a third program that downloads a new version for the server from time to time, which requires the server to end its work and to restart. That's why what I was thinking about is a shell script / batch file that loops forever and starts the server in each loop and waits until it dies, then again starts it. In such case I just need to exit the master process and the batch script will restart it. May be there is better way, but because it is forked process I can't just use exec $0. Perhaps you can offer a better way of doing it. If it is not a forking script I am just using 'exec $0' and it restarts just perfect. | [reply] |
Hmm. Pile upon pile of... nevermind. ;-)
Anyway, since this is for Windows, with emulated fork, I'll just pass you some thougths:
- fork is emulated using threads... Doesn't that imply that if the parent process quits, that all children will go, too?
- AFAIK there's no such things as zombie processes on Windows. It just doesn't work that way. Thus wait, and waitpid probably are unnecessary.
There used to be a fantastic page explaining how fork is supposed to work and how it is emulated on Windows, in Perl, using a comic strip, in Mr. Peabody Explains fork(). The domain (temporarily?) just vanished, according to Google's cache: "This page will be going away on 1/14/2006. This is a planned outage, and will last approximately 90 days." So here's hoping it still will come back, one day...
Meanwhile, here's what I think that should be a generic solution, even for Unix: instead of just throwing the kids' ids away, just keep track of them yourself: store them in a complex data structure, and keep an eye on them in the REAP routine. I propose using a hash, that's the easiest for lookup. Here's some untested code, adapted from your original:
my %kids;
sub REAP {
while((my $deceased = waitpid(-1, WNOHANG)) != -1) {
delete $kids{$deceased};
}
$SIG{CHLD} = \&REAP;
}
$SIG{CHLD} = \&REAP;
while ($new_sock = $sock->accept()) {
if(my $kid = fork) {
$kids{$kid} = 1;
# parent closes the client since
# it is not needed
close $new_sock;
} else {
die unless defined $kid; # if fork failed
# the kid's work
# ...
exit;
}
}
To kill them all, just work your way through keys %kids. kill apparently can handle them all without loop.
delete $SIGNAL, keys %kids;
I don't know what signal you're supposed to be using.
Like I said, I don't expect the REAP routine to ever be triggered on Windows, but I'm not sure. In that case, the %kids hash would only grow over time, but probably not at a huge rate, and thus, would not be a real problem.
| [reply] [d/l] [select] |