While playing with standard library i've found a strange difference between python2 and python3. If i try to catch a signal in python2 while TCPServer is running in a different thread the signal does not get handled, but in python3 it does.
Here is a script that reproduces the problem
import signal
import threading
import sys
if sys.version_info > (3,0):
from socketserver import TCPServer, BaseRequestHandler
else:
from SocketServer import TCPServer, BaseRequestHandler
def shutdown(signum, frame):
print("Shutting down server thread")
server.shutdown()
server = TCPServer(
('127.0.0.1', 7654),
BaseRequestHandler
)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_thread = threading.Thread(target=server.serve_forever)
print("Starting server thread")
server_thread.start()
print("Waiting for server thread to shut down")
server_thread.join()
print("Server thread terminated")
This is the output from python3:
Starting server thread
Waiting for server thread to shut down
^CShutting down server thread
Server thread terminated
And this is from python2:
Starting server thread
Waiting for server thread to shut down
^CKilled
"^C" is a keyboard interrupt and "Killed" is sigkill that i sent to a process.
Why shutdown was not called?
For me it seems thread.join() makes some lock and prevents from catching the signal.
I've tested the following code in Python 2.7 and it seems to work:
import time
import signal
import threading
import sys
if sys.version_info > (3,0):
from socketserver import TCPServer, BaseRequestHandler
else:
from SocketServer import TCPServer, BaseRequestHandler
def shutdown(signum, frame):
print("Shutting down server thread")
server.running = False
server.shutdown()
server = TCPServer(
('127.0.0.1', 7654),
BaseRequestHandler
)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_thread = threading.Thread(target=server.serve_forever)
print("Starting server thread")
server_thread.start()
server.running = True
print("Waiting for server thread to shut down")
while server.running:
time.sleep(1)
server_thread.join()
print("Server thread terminated")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With