Hide Forgot
Description of problem: A process forked in a thread will become an orphan process, and until manually kill it the process will be alive. Version-Release number of selected component (if applicable): RHEL7: python-2.7.5 Fedora23: python-2.7.10 and python-3.4.3 How reproducible: Run the demo program as follows Steps to Reproduce: 1. python ./demo.py # python3 ./demo.py 2. ps -LwAeo comm,args,pid,ppid,tid,pgid,tpgid,sid,%cpu,\ %mem,bsdstart,bsdtime,c,flags,nlwp,wchan,nwchan,wchan | \ grep '\[python' | grep -v grep Actual results: There is an orphan process that has two threads. Expected results: The demo program quit successfully. Additional info: ############demo.py########################### #!/usr/bin/env python import os import sys try: import Tkinter except ImportError: import tkinter try: import thread except ImportError: import _thread as thread def demo(): try: pid = os.fork() except RuntimeError: sys.exit(0) if pid == 0: os.close(r) os.write(w, "Child".encode('utf8')) sys.exit(0) else: os.close(w) if __name__ == "__main__": r, w=os.pipe() thread.start_new_thread(demo, ()) sys.stdout.write(str(os.read(r, 5))) ##############END########################
The Tkinter/tkinter module will add a child handler, which is used by tcl/tk to do the tcl/tk event queue and notifier interfaces, to the fork system call. When forking a process, the fork child handler will start a thread in the child process. And when the process done, the exit system call will tell the thread created by the fork child handler to quit. While when a process forked in a thread, the thread created by the fork child handler left, and seems the exit system call didn't work.
This bug cause building python-2.7.5 package on brew system stall.
The tkinter module creates a new thread on fork(), the thread create pipes and does select() on the read side, which blocks the thread from exiting. If I did this change to the test py file, test works for me, no thread left behind # diff -u bz1313148.py bz1313148.py.new --- bz1313148.py 2016-03-04 15:04:28.735037233 +0800 +++ bz1313148.py.new 2016-03-04 15:04:35.678778973 +0800 @@ -20,7 +20,7 @@ if pid == 0: os.close(r) os.write(w, "Child".encode('utf8')) - sys.exit(0) + os._exit(0) else: os.close(w) sys.exit() ends up calling _exit(), which only terminates the calling thread. On the other hand, os._exit() ends up calling exit_group(), which terminates all threads in the calling process's thread group. But I'm not sure if it's a python/tkinter bug or a misuse of the module.
*** This bug has been marked as a duplicate of bug 1313259 ***