python - How to explain the reentrant RuntimeError caused by printing in signal handlers? -


code:

# callee.py import signal import sys import time   def int_handler(*args):     in range(10):         print('interrupt', args)     sys.exit()   if __name__ == '__main__':      signal.signal(signal.sigint, int_handler)     signal.signal(signal.sigterm, int_handler)     while 1:         time.sleep(1) 

# caller.py import subprocess import sys   def wait_and_communicate(p):     out, err = p.communicate(timeout=1)     print('========out==========')     print(out.decode() if out else '')     print('========err==========')     print(err.decode() if err else '')     print('=====================')   if __name__ == '__main__':      p = subprocess.popen(         ['/usr/local/bin/python3', 'callee.py'],         stdout=sys.stdout,         stderr=subprocess.pipe,     )     while 1:         try:             wait_and_communicate(p)         except keyboardinterrupt:             p.terminate()             wait_and_communicate(p)             break         except subprocess.timeoutexpired:             continue 

simply execute caller.py , press ctrl+c, program raise runtimeerror: reentrant call inside <_io.bufferedwriter name='<stdout>'> randomly. documentation learn signal handlers called asynchronously, , in case 2 signals sigint(ctrl+c action) , sigterm(p.terminate()) sent @ same time, causing race condition.

however, post learn signal module doesn't execute signal handler inside low-level (c) handler. instead, it sets flag, , interpreter checks flag between bytecode instructions , invokes python signal handler. in other words, while signal handlers may mess control flow in main thread, bytecode instruction atomic.

this seems contradict result of example program. far concerned, print , implicit _io.bufferedwriter both implemented in pure c, , calling print function should consume 1 bytecode instruction (call_function). confused: within 1 uninterrupted instruction on 1 thread, how can function reentrant?

i'm using python 3.6.2.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -