2 minute read

I don’t know why, but this is often overlooked by many people so I’ll put it here. These are snippets to ensure you’re running only one instance of a program for various platforms/languages:

  • When you create a program on Windows, you use mutexs to ensure your application is running as a single instance.
  • When you create a script or program on Linux and similar systems, you use file locks. When the process dies, the lock get lost. So you don’t need to make a pid file and check the date and so on, like i’ve seen too many times. It’s unreliable, slow, etc.

The one thing you want to make sure with all these methods, is that your lock file has a unique, reserved name, only used by you. Same for the name of the mutexes!

In plain C

We use the fnctl “file descriptor manipulation” functionality that let us lock files.

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#define LOCK "/var/lock/myprogram.lock"

int main(void) {
    int fd = 0;
    for(; i > 0; i--) {
        if((fd = open(LOCK, O_RDWR|O_CREAT|O_EXCL, 0444)) == -1) {
            fprintf(stderr, "Program already running\n");
            return 1;
         }
    }

   //Program code...

    close(fd);
    unlink(LOCK);
    return 0;
}

In a bash shell

There is unfortunately, no fcntl support in bash. So there’s a small program, called flock.

It uses the flock (as the name implies) function instead. It is usually part of the util-linux package and it’s usually installed by default everywhere. Note that, the lock file won’t be deleted. One difference of flock, is that it will not work for example, on NFS.

A small work-around could be to use the above fnctl-based locking program with an exec command as “your code”, and call it from bash.

Due to the nature of file locking, the flock program must wrap around your script, this is done either by letting it start your script:

flock -xn /var/lock/myprogram.lock myprogram

Either by wrapping it inside your script (if you have no control over what calls your script):

(
    flock -ns 200
    # your script...
) 200 > /var/lock/myprogram.lock

In python

Python is being nice and supports fcntl. Put it at the top of your script’s code or main function.

Fast & easy.

#Check if we are already running an instance
import fcntl, sys, os
#You can use a /var/lock/myprogram.lock and do not store the PID of course
#but since we can do it, its sometimes handful to have it
pid_file = '/var/run/myprogram.pid'
fp = open(pid_file, 'w')
try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
        # another instance is running
        sys.exit(1)
fp.write(str(os.getpid()))
# Your code

fp.close()
os.unlink(pid_file)

In C# / .NET

This method is similar as on Win32, since, well, .NET is originally made by Microsoft right? It’s not so bad anyway.

bool instance = true;
using (Mutex mutex = new Mutex(true, "myProgram", out instance))
{
if (instance)
{
//Your code, just putting visual studio default with WinForms here...
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}

Updated:

Comments