Last active
July 27, 2024 11:18
-
-
Save JavaScriptDude/b436bfda31e765ef7a9916890c786138 to your computer and use it in GitHub Desktop.
Cross Platform Example of Single Instance Checking in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time, sys, os | |
class SingleInstanceChecker: | |
def __init__(self, id): | |
if isWin(): | |
ensure_win32api() | |
self.mutexname = id | |
self.lock = win32event.CreateMutex(None, False, self.mutexname) | |
self.running = (win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS) | |
else: | |
ensure_fcntl() | |
self.lock = open(f"/tmp/isnstance_{id}.lock", 'wb') | |
try: | |
fcntl.lockf(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB) | |
self.running = False | |
except IOError: | |
self.running = True | |
def already_running(self): | |
return self.running | |
def __del__(self): | |
if self.lock: | |
try: | |
if isWin(): | |
win32api.CloseHandle(self.lock) | |
else: | |
os.close(self.lock) | |
except Exception as ex: | |
pass | |
# --------------------------------------- | |
# Utility Functions | |
# Dynamically load win32api on demand | |
# Install with: pip install pywin32 | |
win32api=winerror=win32event=None | |
def ensure_win32api(): | |
global win32api,winerror,win32event | |
if win32api is None: | |
import win32api | |
import winerror | |
import win32event | |
# Dynamically load fcntl on demand | |
# Install with: pip install fcntl | |
fcntl=None | |
def ensure_fcntl(): | |
global fcntl | |
if fcntl is None: | |
import fcntl | |
def isWin(): | |
return (os.name == 'nt') | |
# --------------------------------------- | |
def main(argv): | |
_timeout = 10 | |
print("main() called. sleeping for %s seconds" % _timeout) | |
time.sleep(_timeout) | |
print("DONE") | |
if __name__ == '__main__': | |
SCR_NAME = "my_script" | |
sic = SingleInstanceChecker(SCR_NAME) | |
if sic.already_running(): | |
print("An instance of {} is already running.".format(SCR_NAME)) | |
sys.exit(1) | |
else: | |
main(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great job @JavaScriptDude !