python守护程序线程退出但进程仍然在后台运行

时间:2015-10-15 23:50:56

标签: python multithreading

我正在使用python 2.7并且Python程序在主程序退出后不会终止其进程。 (在ubuntu机器上用ps -ax命令检查)

我有以下的线程类,

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 Killer所建议的,我在我的线程类中添加了以下方法,

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

并在我的sample.py中使用 os.kill(c.getProcessID(),SIGTERM)。该计划根本没有退出。

1 个答案:

答案 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)应该没问题,所以稍后再次调用{0}会不会对任何事情造成伤害。