What is the best way to prevent a Linux program/daemon from being executed more than once at a given time?
7 Answers
The most common way is to create a PID file: define a location where the file will go (inside /var/run is common). On successful startup, you'll write your PID to this file. When deciding whether to start up, read the file and check to make sure that the referenced process doesn't exist (or if it does, that it's not an instance of your daemon: on Linux, you can look at /proc/$PID/exe
). On shutdown, you may remove the file but it's not strictly necessary.
There are scripts to help you do this, you may find start-stop-daemon
to be useful: it can use PID files or even just check globally for the existence of an executable. It's designed precisely for this task and was written to help people get it right.

- 39,182
- 5
- 68
- 95
-
It's usually a good idea to use `flock` on such a pid file to ensure the process using the pid is, in fact, yours. – Hasturkun Sep 14 '10 at 16:26
-
Yeah, put an exclusive lock on the pid file, and leave it there. If the lock fails, another instance is running. – MarkR Sep 15 '10 at 05:48
-
That depends on whether you're writing the PID file using the daemon process itself or not: if you're using `start-stop-daemon` or similar, you can't lock the file that way. Besides, even if you manage to get the lock you should still check the PID contained within the file so I'm not sure it gains you much. – Andrew Aylett Sep 15 '10 at 08:38
Use the boost interprocess library to create a memory block that will be created by the process. If it already exists, it means that there is another instance of the process. Exit.
The more precise link to what you need would be this one.
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/scoped_ptr.hpp>
int main()
{
using boost::interprocess;
boost::scoped_ptr<shared_memory_object> createSharedMemoryOrDie;
try
{
createSharedMemoryOrDie.reset(
new shared_memory_object(create_only, "shared_memory", read_write));
} catch(...)
{
// executable is already running
return 1;
}
// do your thing here
}

- 16,798
- 8
- 46
- 66
-
2Will this work if the process is killed with -9 before it can free shared_memory_object? – rustyx Apr 04 '17 at 11:18
-
Will this work if the process is killed with -9 before it can free shared_memory_object? – abhiarora May 21 '20 at 07:42
If you have access to the code (i.e. are writing it):
- create a temporary file, lock it, remove when done,
return 1;
if file exists, or, - list processes,
return 1;
if the process name is in the list
If you don't:
- create a launcher wrapper to the program that does one of the above

- 79,602
- 28
- 170
- 210
-
Ok, that sounds interesting. But what if the process is killed before it can remove the temporary file? – Jan Deinhard Sep 14 '10 at 07:51
-
That is a problem, yes. You could use the second method to avoid this problem, though. – Delan Azabani Sep 14 '10 at 07:53
-
Or have a normal file like `application.pid` on which to get an exclusive lock, which at the end of the application would be released. – mhitza Sep 14 '10 at 08:08
I think this scheme should work (and is also robust against crashes):
Precondition: There is a PID file for your application (typically in /var/run/)
1. Try to open the PID file
2. If it does not exist, create it and write your PID to it. Continue with the rest of the program
3. If it exist, read the PID
4. If the PID is still running and is an instance of your program, then exit
5. If the PID does not exist or is used by another program, remove the PID file and go to step 2.
6. At program termination, remove the PID file.
The loop in step 5 ensures that, if two instances are started at the same time, only one will be running in the end.

- 15,488
- 4
- 32
- 41
-
I wouldn't remove the pid file if it's not got your pid in, as that can introduce a race condition. – MarkR Sep 15 '10 at 05:50
I do not know what your exact requirement is but I had a similar requirement; in that case I started my daemon from a Shell script ( it was a HP-UX machine) and before starting the daemon I checked if an exec by same name is already running. If it is; then don't start a new one.
By this way I was also able control the number of instances of a process.

- 5,749
- 3
- 22
- 18
-
-
You can list the processes running using 'ps' command. At least in HP-UX. – Vaibhav Sep 14 '10 at 09:47
-
1I have a script that works like this. It's very useful, but it's impossible to do this reliably. E.g. if the exec is a script what you'll see running is the interpreter (sh, or perl, or whatever) and the name of the script is the first argument. But it's also possible to exec a program with a fake name in which case you won't actually know how to identify it. You can also look at the /proc filesystem. But there's no way to make this 100% reliable. – reinierpost Sep 14 '10 at 09:50
Have a pid file and on the startup do a 'kill -0 <pid>'
. Where is the value read from file. If the response is != 0 then the daemon is not alive and you might restart it
Another approach would be to bind to a port and handle the bind exception on the second attempt to start the daemon. If the port is in use then exit otherwise continue running the daemon.

- 3,185
- 1
- 27
- 32
-
3The kill -0 will only tell you the process exists, not that it's your daemon. I have seen an annoying bug where (at boot time where pid numbers are sequential) another process takes the same pid, and caused a daemon to erroneously fail to startup. – MarkR Sep 15 '10 at 05:49
I believe my solution is the simplest:
(don't use it if racing condition is a possible scenario, but on any other case this is a simple and satisfying solution)
#include <sys/types.h>
#include <unistd.h>
#include <sstream>
void main()
{
// get this process pid
pid_t pid = getpid();
// compose a bash command that:
// check if another process with the same name as yours
// but with different pid is running
std::stringstream command;
command << "ps -eo pid,comm | grep <process name> | grep -v " << pid;
int isRuning = system(command.str().c_str());
if (isRuning == 0) {
cout << "Another process already running. exiting." << endl;
return 1;
}
return 0;
}

- 1,401
- 5
- 15
- 33