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
A process forked in a thread will become an orphan process and the orphan one...
Status: CLOSED DUPLICATE of bug 1313259
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: python (Show other bugs)
7.2
Unspecified Unspecified
high Severity unspecified
: rc
: ---
Assigned To: Charalampos Stratakis
BaseOS QE - Apps
: Patch
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2016-03-01 00:32 EST by Xibo Ning
Modified: 2016-03-12 09:22 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2016-03-12 09:22:15 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Xibo Ning 2016-03-01 00:32:27 EST
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 01:02:49 EST
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 01:04:54 EST
This bug cause building python-2.7.5 package on brew system stall.
Comment 5 Eryu Guan 2016-03-04 02:23:22 EST
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 09:22:15 EST

*** 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.