I have a question regarding signals and a threaded application.
I just inherited some very old DOS code that run under a quasi-real time O/S called AMX (something from the late 80’s - early 90’s). In this quasi-real time O/S the tasks were basically functions linked into the ‘kernal’ running in unprotected memory (similar to what vxWorks is now).
We are totally re-writing everything to run under QNX but I was first asked to port the existing stuff to QNX as a proof of concept to get a baseline test with the hardware. This is a very quick/dirty port not intended to be every deployed or used for anything other than a test.
So what I decided is to create one multi-threaded process because the old code transfers pointers and access global variables and other such stuff.
Now at some point the user can from the keyboard tell the system to shutdown. All the threads should then orderly shut down and leave the hardware in a nice state or save data to files etc.
In all the former ‘functions’ that ran as threads I simply added the following code:
extern int runFlag; // This is a global
while(runFlag)
{
// former code that is reply blocked for a timer/message/hardware etc.
}
Then I added a signal handler for SIGUSR1 and inside there I simply set the flag to false when the signal is raised (which happens when the user requests shutdown of the system).
Now, there are about 15 threads running in total, most of which are blocked on hardware/message queues/timers etc.
I expected that when the signal was raised that it would be delivered to every thread in my app, they would break out of their receive loops, see the flag was false and run their exit routines. But it doesn’t appear this is the case because when I do send the signal only one thread actually exits (which ever thread happens to be active at that moment) and the rest stay blocked on their conditions until they unblock and check the while loop.
So obviously the whole app doesn’t shut down gracefully. Yet if I send an unhandled signal to the app (such as SIGINT) everything immediately shutdown.
So my question is, how do multi-threaded apps such as resource managers shut down gracefully if a signal is delivered that requires them to shutdown and inform every thread of the shutdown? Something really simple would be ideal because this isn’t really code that’s going to be kept when the final re-design is done under QNX.
TIA,
Tim
P.S. One more strange thing. When all the threads are running and I am getting keyboard input from the user if I enter a CTRL-C all the threads shutdown except one that shows it’s reply blocked on the serial port (where I read data). For some reason this thread never dies. Even doing a kill -9 # doesn’t delete it from the list of tasks running. I can run my app again with no problems so it’s not interfering with the reading from the serial port and if I CTRL-C again I get another instance of a task reply blocked on the serial port. Anyone know why this might be?