[ACCEPTED]-How to block running two instances of the same program?-c++

Accepted answer
Score: 36

There are several methods you can use to 15 accomplish only allowing one instance of 14 your application:

Method 1: Global synchronization object or memory

It's usually done by creating 13 a named global mutex or event. If it is 12 already created, then you know the program 11 is already running.

For example in windows 10 you could do:

    #define APPLICATION_INSTANCE_MUTEX_NAME "{BA49C45E-B29A-4359-A07C-51B65B5571AD}"

    //Make sure at most one instance of the tool is running
    bool bAlreadyRunning((::GetLastError() == ERROR_ALREADY_EXISTS));
    if (hMutexOneInstance == NULL || bAlreadyRunning)
        throw std::exception("The application is already running");

Method 2: Locking a file, second program can't open the file, so it's open

You could also exclusively 9 open a file by locking it on application 8 open. If the file is already exclusively 7 opened, and your application cannot receive 6 a file handle, then that means the program 5 is already running. On windows you'd simply 4 not specify sharing flags FILE_SHARE_WRITE on the file you're 3 opening with CreateFile API. On linux you'd use flock.

Method 3: Search for process name:

You 2 could enumerate the active processes and 1 search for one with your process name.

Score: 5

Your method of writing the process pid to 11 a file is a common one that is used in many 10 different established applications. In fact, if 9 you look in your /var/run directory right now I 8 bet you'll find several *.pid files already.

As 7 you say, it's not 100% robust because there 6 is chance of the pids getting confused. I 5 have heard of programs using flock() to lock an 4 application-specific file that will automatically 3 be unlocked by the OS when the process exits, but 2 this method is more platform-specific and 1 less transparent.

Score: 4

I actually use exactly the process you describe, and 5 it works fine except for the edge case that 4 happens when you suddenly run out of disk 3 space and can no longer create files.

The 2 "correct" way to do this is probably 1 to use shared memory: http://www.cs.cf.ac.uk/Dave/C/node27.html

Score: 4

It is very un-unix to prohibit multiple 9 instances of a program to run.

If the program 8 is, say, a network daemon, it doesn't need 7 to actively prohibit multiple instances--only 6 the first instance gets to listen to the 5 socket, so subsequent instances bomb out 4 automatically. If it is, say, an RDBMS, it 3 doesn't need to actively prohibit multiple 2 instances--only the first instance gets 1 to open and lock the files. etc.

Score: 1

If you want something that's bog standard, then 13 using a file as a 'lock' is pretty much 12 the way to go. It does have the drawback 11 that you mentioned (if your app doesn't 10 clean up, restarting can be an issue).

This 9 method is used by quite a few applications, but 8 the only one I can recall off the top of 7 my head is VMware. And yes, there are times 6 when you have to go in and delete the '*.lck' when 5 things get wedged.

Using a global mutex or 4 other system object as mentioned by Brian Bondy is 3 a better way to go, but these are platform 2 specific, (unless you use some other library 1 to abstract the platform specifics away).

Score: 0

I don't have a good solution, but two thoughts:

  1. You 7 could add a ping capability to query the 6 other process and make sure it's not an 5 unrelated process. Firefox does something 4 similar on Linux and doesn't start a new 3 instance when one is already running.

  2. If 2 you use a signal handler, you can ensure 1 the pid file is deleted on all but a kill -9

Score: 0

I scan the process list looking for the 10 name of my apps executable with matching 9 command line parameters then exit if there 8 is a match.

My app can run more than once, but 7 I don't want it running the same config 6 file at the same time.

Obviously, this is 5 Windows specific, but the same concept is 4 pretty easy on any *NIX system even without 3 specific libraries simply by opening the 2 shell command 'ps -ef' or a variation and 1 looking for your app.

   '     Sub: CheckForProcess()
   '  Author: Ron Savage
   '    Date: 10/31/2007
   ' This routine checks for a running process of this app with the same
   ' command line parameters.
   Private Function CheckForProcess(ByVal processText As String) As Boolean
      Dim isRunning As Boolean = False
      Dim search As New ManagementObjectSearcher("SELECT * FROM Win32_process")
      Dim info As ManagementObject
      Dim procName As String = ""
      Dim procId As String = ""
      Dim procCommandLine As String = ""

      For Each info In search.Get()
         If (IsNothing(info.Properties("Name").Value)) Then procName = "NULL" Else procName = Split(info.Properties("Name").Value.ToString, ".")(0)
         If (IsNothing(info.Properties("ProcessId").Value)) Then procId = "NULL" Else procId = info.Properties("ProcessId").Value.ToString
         If (IsNothing(info.Properties("CommandLine").Value)) Then procCommandLine = "NULL" Else procCommandLine = info.Properties("CommandLine").Value.ToString

         If (Not procId.Equals(Me.processId) And procName.Equals(processName) And procCommandLine.Contains(processText)) Then
            isRunning = True
         End If

      Return (isRunning)
   End Function
Score: 0

I found a cross platform way to do this 1 using boost/interprocess/sync/named_mutex. Please refer to this answer https://stackoverflow.com/a/42882353/4806882

More Related questions