Ensure a single instance of an application in Linu

2019-01-03 22:15发布

I'm working on a GUI application in WxPython, and I am not sure how I can ensure that only one copy of my application is running at any given time on the machine. Due to the nature of the application, running more than once doesn't make any sense, and will fail quickly. Under Win32, I can simply make a named mutex and check that at startup. Unfortunately, I don't know of any facilities in Linux that can do this.

I'm looking for something that will automatically be released should the application crash unexpectedly. I don't want to have to burden my users with having to manually delete lock files because I crashed.

12条回答
Viruses.
2楼-- · 2019-01-03 22:49

If you create a lock file and put the pid in it, you can check your process id against it and tell if you crashed, no?

I haven't done this personally, so take with appropriate amounts of salt. :p

查看更多
Summer. ? 凉城
3楼-- · 2019-01-03 22:51

The Right Thing is advisory locking using flock(LOCK_EX); in Python, this is found in the fcntl module.

Unlike pidfiles, these locks are always automatically released when your process dies for any reason, have no race conditions exist relating to file deletion (as the file doesn't need to be deleted to release the lock), and there's no chance of a different process inheriting the PID and thus appearing to validate a stale lock.

If you want unclean shutdown detection, you can write a marker (such as your PID, for traditionalists) into the file after grabbing the lock, and then truncate the file to 0-byte status before a clean shutdown (while the lock is being held); thus, if the lock is not held and the file is non-empty, an unclean shutdown is indicated.

查看更多
戒情不戒烟
4楼-- · 2019-01-03 22:53

Can you use the 'pidof' utility? If your app is running, pidof will write the Process ID of your app to stdout. If not, it will print a newline (LF) and return an error code.

Example (from bash, for simplicity):

linux# pidof myapp
8947
linux# pidof nonexistent_app

linux#
查看更多
够拽才男人
5楼-- · 2019-01-03 22:54

The set of functions defined in semaphore.h -- sem_open(), sem_trywait(), etc -- are the POSIX equivalent, I believe.

查看更多
Rolldiameter
6楼-- · 2019-01-03 22:59

wxWidgets offers a wxSingleInstanceChecker class for this purpose: wxPython doc, or wxWidgets doc. The wxWidgets doc has sample code in C++, but the python equivalent should be something like this (untested):

  name = "MyApp-%s" % wx.GetUserId()
  checker = wx.SingleInstanceChecker(name)
  if checker.IsAnotherRunning():
      return False
查看更多
仙女界的扛把子
7楼-- · 2019-01-03 22:59

Look for a python module that interfaces to SYSV semaphores on unix. The semaphores have a SEM_UNDO flag which will cause the resources held by the a process to be released if the process crashes.

Otherwise as Bernard suggested, you can use

import os
os.getpid()

And write it to /var/run/application_name.pid. When the process starts, it should check if the pid in /var/run/application_name.pid is listed in the ps table and quit if it is, otherwise write its own pid into /var/run/application_name.pid. In the following var_run_pid is the pid you read from /var/run/application_name.pid

cmd = "ps -p %s -o comm=" % var_run_pid
app_name = os.popen(cmd).read().strip()
if len(app_name) > 0:
    Already running
查看更多
登录 后发表回答