0

I have a Python script that starts up when Pi boots. However, it may be restarted remotely, or I may want to kill it before re-launching it from Visual Studio for debugging/further development. Therefore, when this script launches, it needs to check if there are other instances of it, and kill them, without killing itself. So, at the beginning of the script, I have this code:

import os
import subprocess

def killOtherScriptInstances():
    myPID = os.getpid() 
    pids = list(map(int, subprocess.check_output('pgrep -f test.py', shell=True).decode('UTF-8').splitlines()))

    for pid in pids:
        if pid != myPID:
            subprocess.check_output('kill -9 ' + str(pid), shell=True)

killOtherScriptInstances()

If my script is started from shell, this function works just fine. However, if the script is launched from Visual Studio Code with RemoteSSH, for whatever reason pgrep -f test.py reports two PIDs for the current script instance (even if there were no instances running prior). It kills one that does not match the PID reported by os.getpid(), but that still terminates the current instance of the script.

Can someone explain why running my script from shell (python3 test.py) produces one instance and one PID for this script, but running the same script from Visual Studio Code produces two? How do I work around this issue?

J R
  • 227
  • 3
  • 8
  • 1
    Just run it as a systemd service, and restart it using `systemctl` instead. That allows you to remove all this logic from your code. – larsks Jul 11 '23 at 20:14
  • @larsks - unfortunately, I can't, since I still need to run it from Visual Studio Code when I develop it. And there are other scenarios when the script might be started even though it is already running, which are beyond the scope of this question. – J R Jul 11 '23 at 20:30
  • Maybe instead of trying to find and kill all other processes of the script running, set a semaphore that the script checks for and it kills itself if that semaphore is missing. For example, in the main loop, check that a particular environment variable is set to some truthy value. If its not, kill the script. On script startup you could either exit with an error if the flag isn't set, or you could have it set the flag to false, wait a sufficient period of time for running scripts to end, and then set it back to True. – nigh_anxiety Jul 12 '23 at 02:40
  • @nigh_anxiety, thanks for that suggestion, but in cases when a new instance of script is launched, I do need that specific instance to remain, and previous ones to close, not the other way around. – J R Jul 12 '23 at 09:45
  • Ok, so then just set your script to kill the semaphore on startup, wait X seconds for the previous script to cleanup, and then set the semaphore before entering the main loop. This would also allow you to stop any running instance by clearing the semaphore flag manually in the terminal. – nigh_anxiety Jul 12 '23 at 09:54
  • @nigh_anxiety environments are not shared between processes – rioV8 Jul 12 '23 at 10:24
  • @riov8 yeah, I was reflecting back on years working in MUMPS systems where we can just set a global. Easy replacement though - the existence or non-existance of any empty file, as the filesystem is shared across processes. – nigh_anxiety Jul 12 '23 at 13:28

0 Answers0