Search code examples
pythonwindowsmultithreadingprocessflock

Python check if another python application is running


I have two applications (compiled from python, running on Windows only). The first one is scheduled: it starts, launches several instances of another application and dies. Also, this scheduled app should check if previously started instances of child app are still running.

To implement this check I tried to use files lock method:

  1. Create file in child app and get explicit lock on it. In case if app crashes the lock should be released automatically.
  2. Check this file from scheduled app. If it is locked - that means that child app is still running.

This is very easy to implement in PERL, but I've met some troubles in python.

I tried to use win32 API (cut required part of code from portalocker).

Here is the test script:

import os
import win32con
import win32file
import pywintypes
import sys
import time
import threading

def createLockFile(filePath = "c:\\\\test.tmp"):
    file = open(filePath, "a+")
    hfile = win32file._get_osfhandle(file.fileno())
    win32file.LockFileEx(hfile, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, pywintypes.OVERLAPPED())

def lockFile(filePath = "c:\\\\test.tmp"):
    t = threading.Thread(target=createLockFile, args=(filePath,))
    t.start()

def checkFileLock(filePath = "c:\\\\test.tmp"):
    log = open(filePath, "a+")
    #here should be IOError: [Errno 13] in case of error
    print 'File is not locked'

def go():
    print 'start'
    lockFile()
    print 'file locked'
    print 'sleeping'
    time.sleep(30)
    print 'getting up'

I open two instances of Python shell and import this script. Then I launch go() method in one of it and while it is sleeping I launch checkFileLock() function to check if file is actually locked... And it is not.

I also tried to leave sys.stdin.readline like it is done in portalocker and in this case the file is really locked. But there is no need to listen to stdin in my app...

So I've created infinite loop in the thread which creates the lock. In this case the file is also locked but it is not released even after I close the Python shell which also is not correct.

I will be very please to hear how to solve the problems with locking files from Python in Windows. If you have any other working methods of how to definitely know if the process is still running I would like to hear it also.


Solution

  • I use the code here to do it. In my case, I'm always running in Windows, so I removed the platform checks. It's worked well for me.

    import os, time, sys
    
    class SingleInstance:
        def __init__(self, filename):
            self.lockfile = filename
    
            try:
                # file already exists, we try to remove (in case previous execution was interrupted)
                if os.path.exists(self.lockfile):
                    os.unlink(self.lockfile)
    
                self.fd =  os.open(self.lockfile, os.O_CREAT|os.O_EXCL|os.O_RDWR)
    
            except OSError as e:
                if e.errno == 13:
                    print("Another instance is already running, quitting.")
                    #sys.exit(-1)
    
                print(e.errno)
                raise
    
            except Exception as x:
                print(x)
    
        def __del__(self):
            import sys
    
            if hasattr(self, 'fd'):
                os.close(self.fd)
                os.unlink(self.lockfile)