Bug 1313148 - A process forked in a thread will become an orphan process and the orphan one will be alive until we manually kill it
Summary: A process forked in a thread will become an orphan process and the orphan one...
Keywords:
Status: CLOSED DUPLICATE of bug 1313259
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: python
Version: 7.2
Hardware: Unspecified
OS: Unspecified
high
unspecified
Target Milestone: rc
: ---
Assignee: Charalampos Stratakis
QA Contact: BaseOS QE - Apps
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-03-01 05:32 UTC by Xibo Ning
Modified: 2016-03-12 14:22 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-03-12 14:22:15 UTC
Target Upstream Version:


Attachments (Terms of Use)

Description Xibo Ning 2016-03-01 05:32:27 UTC
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########################

Comment 2 Xibo Ning 2016-03-01 06:02:49 UTC
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.

Comment 3 Xibo Ning 2016-03-01 06:04:54 UTC
This bug cause building python-2.7.5 package on brew system stall.

Comment 5 Eryu Guan 2016-03-04 07:23:22 UTC
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.

Comment 8 Charalampos Stratakis 2016-03-12 14:22:15 UTC

*** This bug has been marked as a duplicate of bug 1313259 ***


Note You need to log in before you can comment on or make changes to this bug.