On Sat, Feb 05, 2005 at 02:01:47PM +0000, Dale Dunlea wrote:
> > howwever, you would be far better off if you did not use SIGCHLD
> > at all. the advice given earlier, use waitpid(2), is a better
> > approach.
> Why is that? As I understand it, using SIGCHLD is essentially interrupt
> driven, whilst waitpid would be polling.
because over the years signals have had different semantics. originally
they were not reliable - i could send a signal to a process and maybe
the process would get it. maybe not. if a slew of signals were sent
only a few might show up.
the signal api could also cause your program to miss a signal.
sigaction and friends coupled with modern nicies have mostly removed
that issue. but few people i know depend on that.
you can call waitpid with no blocking and unless you're doing it in a
tight loop, it doesn't matter that it's polling. if you have a select
driven program, this is a better design (in pseudo code):
int dead_child_flag = 0
handle_sigchild()
dead_child_flag = 1
main()
install_signal_handler(sigchild, handle_sigchild)
do_forever
select(file_descriptors)
if (dead_child_flag || time() > child_check)
dead_child_flag = 0;
child_check = time() + 600
while (waitpid(child_return_code, non_block))
deal_with_dead_child(child_return_code)
go_do_things_with(file_descriptors)
note that in this example it's possible to have dead_child_flag == 1
and no dead children. if a child dies after dead_child_flag is set to 0
and before the while loop is done, you'll waitpid the child. in the
next do_forever loop you'll see dead_child_flag set to 1 and go look -
that's why waitpid should be set to nonblocking.
if instead you wrote:
if (dead_child_flag || time() > child_check)
child_check = time() + 600
while (waitpid(child_return_code, non_block))
deal_with_dead_child(child_return_code)
dead_child_flag = 0;
go_do_things_with(file_descriptors)
then you might miss a child dying - if it exited between the while loop
exiting and the dead_child_flag being set to 1.
and that's the main problem with signals. loads of subtle errors
can creap into your code that a qa team would probably miss but would
eventually be hit by users. they're handy for things - getting daemons
to reread configs or to exit or whatever - but they should be written
with the knowledge that they might not work. so when the daemon
rereads its config, it should say that to syslog. it's no huge hassle
to run the kill command a few times. it is a hassle to have to bounce a
daemon because it's got loads of zombies trailing after it.
kevin
--
kevin lyda Every gun that is made, every warship launched,
kevin at ie.suberic.net every rocket fired signifies, in the final
http://ie.suberic.net/~kevin/ sense, a theft from those who hunger and are
Dwight Eisenhower, 1953 ----> not fed, those who are cold and are not clothed.
Maintained by the ILUG website team. The aim of Linux.ie is to
support and help commercial and private users of Linux in Ireland. You can
display ILUG news in your own webpages, read backend
information to find out how. Networking services kindly provided by HEAnet, server kindly donated by
Dell. Linux is a trademark of Linus Torvalds,
used with permission. No penguins were harmed in the production or maintenance
of this highly praised website. Looking for the
Indian Linux Users' Group? Try here. If you've read all this and aren't a lawyer: you should be!