[lug] g++ signals and exceptions question
Tkil
tkil at scrye.com
Wed May 15 13:21:14 MDT 2002
>>>>> "jb" == Jonathan Briggs <zlynx at acm.org> writes:
jb> I was thinking of using it in a situation where my program is
jb> doing some processing, and it gets hit with a signal (SIGHUP for
jb> example) telling it to rotate its log files.
jb> My other choice is to check for a signal in my program loop.
That's pretty much your only choice, really. At some point, you have
to look up and see what's changed around you -- the other options all
involve hitting a wall and then trying to pick up the pieces.
jb> Here's an example of how I'd use it:
jb> while(running) {
jb> try {
jb> do_stuff();
jb> } catch( const SIGHUP_exception& e ) {
jb> rotate_logs();
jb> } catch( const signal_exception& e ) {
jb> running = false;
jb> }
jb> }
If you could do this, how far did you get in do_stuff() when the
exception occurs? How do you know to save your current state?
(Remember, C++ exceptions can't resume, so you have to have made some
progress, then stored that progress elsewhere.) (Besides, you don't
want to do much more than set the value of a static global variable
inside a signal handler anyway -- anything more than that is risky.)
I think the fundamental issue is how to interface asynchronous events
(in this case, signals) with synchronous ones (normal program flow, as
well as exceptions). The method I've seen most often is to break up
the work along either time boundaries, or along responsibility
boundaries.
A time boundary solution would be to do work of a particular quantum,
checking state after each bit of work (a scan line rendered, a file
scanned, a directory searched); this has the problem of granularity,
and the possible need to make it adapative.
Breaking the work up along "responsibility" boundaries often leads to
multi-threading or multi-processing solutions; in this case, you could
have a process that does nothing but listen for things to log, write
them to the log files when it happens, and handle rotating the logs.
Even using multiple threads is really just a way of pushing the
polling process down into a library or the operating system; at some
level, the system really needs to ask "is this ready?". The idle
process is really a special way of saying: "Anything ready to do? No?
ok, I'll wait a bit."
I understand how polling can pollute the structure of your program.
My suggestion would be to use multiple threads, so that one can stay
responsive for user input, the other can continue working and check
for state changes at the end of a natural unit of work.
t.
More information about the LUG
mailing list