Created
September 16, 2019 17:19
-
-
Save yinyin/8d1cd7c98596e86c5718e8a313c7474e to your computer and use it in GitHub Desktop.
An experiment of signal reentrance in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
The result of signal handler reentrance in Python 2.7 and 3.7 might different: | |
# For Python 2.7 | |
The signal handler will run in order. | |
``` | |
$ python2 signal_handler_reentrance.py | |
20190917011037:INFO:__main__:PID = 4219 (ref-command: kill -USR1 4219; sleep 2; kill -USR1 4219) | |
20190917011037:DEBUG:__main__:in loop 1 | |
20190917011047:DEBUG:__main__:in loop 2 | |
20190917011048:INFO:__main__:in signal handler: t=1568653848, attempt=0 | |
20190917011049:INFO:__main__:in signal handler: t=1568653848, attempt=1 | |
20190917011049:INFO:__main__:in signal handler: t=1568653848, attempt=2 | |
... | |
20190917011054:INFO:__main__:in signal handler: t=1568653848, attempt=12 | |
20190917011054:INFO:__main__:in signal handler: t=1568653848, attempt=13 | |
20190917011055:INFO:__main__:in signal handler: t=1568653848, attempt=14 | |
20190917011055:INFO:__main__:leaving signal handler: t=1568653848 | |
20190917011055:INFO:__main__:in signal handler: t=1568653855, attempt=0 | |
20190917011056:INFO:__main__:in signal handler: t=1568653855, attempt=1 | |
20190917011056:INFO:__main__:in signal handler: t=1568653855, attempt=2 | |
... | |
20190917011101:INFO:__main__:in signal handler: t=1568653855, attempt=12 | |
20190917011102:INFO:__main__:in signal handler: t=1568653855, attempt=13 | |
20190917011102:INFO:__main__:in signal handler: t=1568653855, attempt=14 | |
20190917011103:INFO:__main__:leaving signal handler: t=1568653855 | |
20190917011103:DEBUG:__main__:in loop 3 | |
``` | |
# For Python 3.7 | |
The 1st signal hander will suspend on the arrival of 2nd signal. | |
``` | |
$ /opt/python-3.7/bin/python3 signal_handler_reentrance.py | |
20190917011309:INFO:__main__:PID = 4350 (ref-command: kill -USR1 4350; sleep 2; kill -USR1 4350) | |
20190917011309:DEBUG:__main__:in loop 1 | |
20190917011318:INFO:__main__:in signal handler: t=1568653998, attempt=0 | |
20190917011318:INFO:__main__:in signal handler: t=1568653998, attempt=1 | |
20190917011319:INFO:__main__:in signal handler: t=1568653998, attempt=2 | |
20190917011319:INFO:__main__:in signal handler: t=1568653998, attempt=3 | |
20190917011320:INFO:__main__:in signal handler: t=1568653998, attempt=4 | |
20190917011320:INFO:__main__:in signal handler: t=1568654000, attempt=0 | |
20190917011320:INFO:__main__:in signal handler: t=1568654000, attempt=1 | |
20190917011321:INFO:__main__:in signal handler: t=1568654000, attempt=2 | |
... | |
20190917011326:INFO:__main__:in signal handler: t=1568654000, attempt=12 | |
20190917011326:INFO:__main__:in signal handler: t=1568654000, attempt=13 | |
20190917011327:INFO:__main__:in signal handler: t=1568654000, attempt=14 | |
20190917011327:INFO:__main__:leaving signal handler: t=1568654000 | |
20190917011327:INFO:__main__:in signal handler: t=1568653998, attempt=5 | |
20190917011328:INFO:__main__:in signal handler: t=1568653998, attempt=6 | |
20190917011328:INFO:__main__:in signal handler: t=1568653998, attempt=7 | |
... | |
20190917011331:INFO:__main__:in signal handler: t=1568653998, attempt=12 | |
20190917011331:INFO:__main__:in signal handler: t=1568653998, attempt=13 | |
20190917011332:INFO:__main__:in signal handler: t=1568653998, attempt=14 | |
20190917011332:INFO:__main__:leaving signal handler: t=1568653998 | |
20190917011332:DEBUG:__main__:in loop 2 | |
``` | |
""" | |
import logging | |
import time | |
import signal | |
import os | |
_log = logging.getLogger(__name__) | |
class SignalHandlerReEntranceExp01: | |
def handler(self, *args, **kwds): # pylint: disable=unused-argument | |
t = int(time.time()) | |
for attempt in range(15): | |
_log.info("in signal handler: t=%d, attempt=%d", t, attempt) | |
time.sleep(0.5) | |
_log.info("leaving signal handler: t=%d", t) | |
def loop(self): | |
loop_count = 0 | |
while True: | |
loop_count = loop_count + 1 | |
try: | |
_log.debug("in loop %d", loop_count) | |
time.sleep(10) | |
except Exception: | |
_log.exception("caught exception in loop %d", loop_count) | |
def main(): | |
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s:%(levelname)s:%(name)s:%(message)s", datefmt="%Y%m%d%H%M%S") | |
exp_obj = SignalHandlerReEntranceExp01() | |
signal.signal(signal.SIGUSR1, exp_obj.handler) | |
pid_value = os.getpid() | |
_log.info("PID = %d (ref-command: kill -USR1 %d; sleep 2; kill -USR1 %d)", pid_value, pid_value, pid_value) | |
exp_obj.loop() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment