Well, this is fun ... for some definition of the word. ;-(
I have a multithreaded app that I want to be able to shut down easily
such as by hitting control-c or sending it a signal. What follows is the
way I have come up with given the common elements of different
environments. Suggestions for improvement would be welcome or you may
just find the convolutions and machinations interesting.
The first issue is that only the main thread can receive signals,
according to
https://docs.python.org/2/library/signal.html
It says: "the main thread will be the only one to receive signals (this
is enforced by the Python signal module, even if the underlying thread
implementation supports sending signals to individual threads)".
That's OK. I can get the main thread to accept suitable signals but then
I need some way for it to tell the other threads to shut themselves down
too. In most (probably all) cases they will be sitting waiting for
network IO.
I could have the main thread set a value in a global variable and then
have the sub-threads check the global in between accesses of the network
in a polling loop (using select() with a timeout). But as has already
been pointed out to me in the thread "Signal SIGINT ignored during
socket.accept" such polling does not sit well with hosted OSes and it
can keep the CPU from remaining at rest in a low-power mode.
I can, however, use select() to monitor two file descriptors. One would
be the socket the thread is using to communicate with the client. The
other would be a control connection from the master thread.
Now to make this cross platform.... According to the opening paragraph
in the following link Windows select() won't work on arbitrary file
descriptors but only works for sockets.
https://docs.python.org/2/library/select.html
Well, that can be dealt with. I thought of using AF_UNIX or something
else but it seems there is nothing else which could be considered
universal and, according to the next link, if socket.AF_UNIX is not
defined then even the Unix protocol is not supported.
https://docs.python.org/2/library/socket.html
Needless to say, on a test Windows machine AF_UNIX is not present. The
only cross-platform option, therefore, seems to be to use each
subthread's select()s to monitor two AF_INET sockets: the one to the
client and a control one from the master thread. I would seem to need IP
socket pairs between the master thread and the subthreads. If the master
thead receives a shutdown signal it will send a shutdown command to each
subthread.
The above seems logical but would use quite a few IP sockets. I cannot
think of a better way, though. Any comments on the ideas above?
James
--
https://mail.python.org/mailman/listinfo/python-list