Message 113086 - Python tracker (original) (raw)
Hi all
My environment is python 2.4.4 on linux. I am encountering hang of pipe.read() in commands.getstatusoutput for multi-threading code.
I have spawned several threads which will call commands.getstatusoutput to run cli. However, pipe.read may hang sometimes. From lsof, we know some pipe handles are not closed in the parent process, after the child process is stopped.
;; -------------------------- Reproduce steps -------------------------- Below are reproduce steps.
Create a python script of /tmp/hang.py, whose content is given below.
Run "service crond stop; python /tmp/hang.py" several times.
The script may probably hang. From lsof of main.py and crond service, we may find one pipe existing in both processes.
If we stop crond to close the pipe, the hang of hang.py will be resolved.
;; -------------------------- Code of hang.py -------------------------- #!/usr/bin/python import commands import datetime import time import os import thread import threading
def thread_run1():
cmd = "hostname"
print "begin to run command:%s" % (cmd)
status, output = commands.getstatusoutput(cmd)
print "pid:%d, name:%s, status:%d, output:%s" % \
(os.getpid(), threading.currentThread().getName(), status, output)
cmd = "ifconfig eth0"
print "begin to run command:%s" % (cmd)
status, output = commands.getstatusoutput(cmd)
print "pid:%d, name:%s, status:%d, output:%s" % \
(os.getpid(), threading.currentThread().getName(), status, output)
cmd = "ifconfig eth1"
print "begin to run command:%s" % (cmd)
status, output = commands.getstatusoutput(cmd)
print "pid:%d, name:%s, status:%d, output:%s" % \
(os.getpid(), threading.currentThread().getName(), status, output)
# cmd = "sh /tmp/subprocess.sh"
cmd = "echo here1; sleep 2; echo here2; sleep 5"
print "begin to run command:%s" % (cmd)
status, output = commands.getstatusoutput(cmd)
print "pid:%d, name:%s, status:%d, output:%s" % \
(os.getpid(), threading.currentThread().getName(), status, output)
def thread_run2():
cmd = "service crond start"
print "begin to run command:%s" % (cmd)
status, output = commands.getstatusoutput(cmd)
print "pid:%d, name:%s, status:%d, output:%s" % \
(os.getpid(), threading.currentThread().getName(), status, output)
if name=='main': print "main function begins." thread_list = [] for i in xrange(1, 10): my_thread = threading.Thread(target = thread_run1) thread_list.append(my_thread)
my_thread = threading.Thread(target = thread_run2)
thread_list.append(my_thread)
for t in thread_list:
t.start()
time.sleep(10)
for t in thread_list:
t.join()
print "main function ends."