I have a Python program with the following structure and necessary imports:
def startLogger(logger_dir):
command0 = 'adb logcat -c'
command1 = 'adb logcat'
command2 = 'python3 '+logger_dir+'main.py'
clear_logcat = subprocess.run(command0.split())
logcatHandle = subprocess.Popen(command1.split(),stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
loggerHandle = subprocess.Popen(command2.split(),stdin=logcatHandle.stdout,shell=False)
return logcatHandle, loggerHandle
def closeLogger(logcatInstance, loggerInstance):
loggerInstance.kill() #Killing it first so that it doesn't break the input PIPE
logcatInstance.kill()
return logcatInstance, loggerInstance
def main():
logger_dir = '/Users/Desktop/logger/'
print("Starting Logger")
logcatHandle, loggerHandle = startLogger(logger_dir)
time.sleep(10)
logcat, logger = closeLogger(logcatHandle, loggerHandle)
main()
The code works fine, I can execute logcat on my Android device, pull in logs, and feed it to my logger giving me the desired output in a text file created by the logger file. But, I cannot kill both processes. I have tried the terminate()
method, os.kill(process.pid, signam.SIGKILL)
, preexec_fn
flag, os.killpg()
, etc methods, but still, the logger keeps on running in the background. What can be the possible issue here?
You should ensure that you're properly closing pipe before killing the processes.
Also, instead of using "kill", use "terminate" to give the process a chance to clean up. If it doesn't, then use "kill".
Then, make sure that the subprocesses don't inherit unnecessary file descriptors which might keep them running.
Considering those changes, try with
import subprocess
import time
import os
import signal
def startLogger(logger_dir):
command0 = 'adb logcat -c'
command1 = 'adb logcat'
command2 = 'python3 ' + logger_dir + 'main.py'
clear_logcat = subprocess.run(command0.split())
logcatHandle = subprocess.Popen(command1.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid)
loggerHandle = subprocess.Popen(command2.split(), stdin=logcatHandle.stdout, preexec_fn=os.setsid) #this starts each subrprocess in a new session
return logcatHandle, loggerHandle
def closeLogger(logcatInstance, loggerInstance):
loggerInstance.terminate()
try:
loggerInstance.wait(timeout=5)
except subprocess.TimeoutExpired:
loggerInstance.kill()
logcatInstance.terminate()
try:
logcatInstance.wait(timeout=5)
except subprocess.TimeoutExpired:
logcatInstance.kill()
os.killpg(os.getpgid(logcatInstance.pid), signal.SIGTERM)
os.killpg(os.getpgid(loggerInstance.pid), signal.SIGTERM)
#(ensures all processes in the process group are terminated, handling any subprocesses that might have been spawned.)
return logcatInstance, loggerInstance
def main():
logger_dir = '/Users/Desktop/logger/'
print("Starting Logger")
logcatHandle, loggerHandle = startLogger(logger_dir)
time.sleep(10)
logcat, logger = closeLogger(logcatHandle, loggerHandle)
print("Logger stopped")
if __name__ == "__main__":
main()
Hope it helps.