我正在使用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"
我仍然看到进程正在运行。 (我现在使用kill -9 17681 17682手动杀死它们)
不确定我在这里缺少什么。
我的问题是, 1)当我在程序中杀死它时,为什么这个过程仍然存在?
2)如果我不打扰它会不会产生任何问题?
3)还有其他更好的方法可以使用线程捕获日志并监控日志吗?
编辑:正如@bug Killer所建议的,我在我的线程类中添加了以下方法,def getProcessID(self):
return os.getpid()
并在我的sample.py中使用 os.kill(c.getProcessID(),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
)应该没问题,所以稍后再次调用{0}会不会对任何事情造成伤害。