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:
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.
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)