2015-10-15 136 views
0

我正在使用python 2.7并且Python主线程在主程序退出后不会终止它的进程。python守护进程线程退出但进程仍在后台运行

我有以下线程类(Ubuntu的机器上-ax命令PS检查这一点),

import os 
import threading 

class captureLogs(threading.Thread): 

''' 
initialize the constructor 
''' 
def __init__(self, deviceIp, fileTag): 
    threading.Thread.__init__(self) 
    super(captureLogs, self).__init__() 
    self._stop = threading.Event() 
    self.deviceIp = deviceIp 
    self.fileTag = fileTag 

def stop(self): 
    self._stop.set() 

def stopped(self): 
    return self._stop.isSet() 
''' 
define the run method 
''' 
def run(self): 
    ''' 
    Make the thread capture logs 
    ''' 
    cmdTorun = "adb logcat > " + self.deviceIp +'_'+self.fileTag+'.log' 
    os.system(cmdTorun) 

而且我创造了另一个文件sample.py一个线程,

import logCapture 
import os 
import time 

c = logCapture.captureLogs('100.21.143.168','somefile') 
c.setDaemon(True) 
c.start() 

print "Started the log capture. now sleeping. is this a dameon?", c.isDaemon() 
time.sleep(5) 
print "Sleep tiime is over" 
c.stop() 

print "Calling stop was successful:", c.stopped() 
print "Thread is now completed and main program exiting" 

我从命令行得到以下输出:

Started the log capture. now sleeping. is this a dameon? True 
Sleep tiime is over 
Calling stop was successful: True 
Thread is now completed and main program exiting 

然后sample.py退出。 但是,当我在终端上使用下面的命令,

ps -ax | grep "adb" 

Output of ps command on ubuntu machine

我仍然看到进程在运行。 (我正在使用kill -9 17681 17682手动杀死它们)

不知道我在这里丢失了什么。

我的问题是, 1)为什么当我已经在程序中杀死它时,进程仍然还活着?

2)如果我不打扰它会产生什么问题吗?

3)有没有其他更好的方法使用线程捕获日志并监视日志?

编辑:由于通过@bug杀手建议的,我添加了以下方法在我的线程类,

def getProcessID(self): 
     return os.getpid() 

和我的示例中使用os.kill(c.getProcessID(),SIGTERM)。 py。该程序根本不退出。

+0

通常,如果您守护进程,即使在parrent进程退出后,它仍会继续在后台运行 –

+0

您是否已将SIGTERM发送到进程 –

+0

我试过了。它似乎不适合我。 :( –

回答

1

很可能是因为您在线程中使用了os.system。即使线程死亡后,从os.system衍生出的进程仍将保持活动状态。实际上,它会永远活着,除非你明确地终止它在你的代码或手工中(它听起来像你最终做的那样),或者产生的过程自己退出。你可以这样做,而不是:

import atexit 
import subprocess 

deviceIp = '100.21.143.168' 
fileTag = 'somefile' 

# this is spawned in the background, so no threading code is needed 
cmdTorun = "adb logcat > " + deviceIp +'_'+fileTag+'.log' 
proc = subprocess.Popen(cmdTorun, shell=True) 

# or register proc.kill if you feel like living on the edge 
atexit.register(proc.terminate) 

# Here is where all the other awesome code goes 

因为所有你正在做的是产卵的过程,创建一个线程来做到这一点是矫枉过正,只有你的程序逻辑复杂化。如上所示,只需在后台生成进程,然后在退出程序时让atexit终止进程。和/或明确地致电proc.terminate;重复调用应该很好(很像close对一个文件对象),因此atexit稍后再调用它应该不会造成任何伤害。

+0

感谢日志建议..这是部分正确..它会杀死其中一个进程,但另一个进程仍然存在。 –

+0

有趣。当你运行''adb logcat>“+ self.deviceIp +'_'+ self.fileTag +'。log''时,是否会产生一个简单的'adb logcat'守护进程?你只会明确地产生一个进程,所以我只能相信这个进程会产生另一个进程(或者启动一个守护进程,但是,这两个PID是连续的,所以它看起来更像一个普通的旧产物)。 – eestrada

+0

是的你是对的:)我正在运行的命令产生另一个简单的'adb logcat'进程。所以我认为这是最终的解决方案。如果我没有收到其他答复,我会选择您的答案作为解决方案。 :) –

相关问题