4

I want only one copy of my program in the system. How can I look for another copies in the system from C-code? I want something like that

# program &
[1] 12586
# program &
Program is already running

The best idea I have is making .lock-files. But I didn't find any guildlines about them.

Thank you.

Ximik
  • 2,435
  • 3
  • 27
  • 53
  • Sounds like you want to run your program as a daemon – Falmarri Nov 22 '10 at 21:41
  • Related thread http://stackoverflow.com/questions/3706917/how-to-prevent-a-linux-program-from-running-more-than-once – Naveen Nov 22 '10 at 21:47
  • It's not a daemon, but something like. The problem is two copies in the same time can crash the data. – Ximik Nov 22 '10 at 21:47
  • Thank you for link. So the seemes like lock files is the best way. But is this all? Sockets and IPC is very "hard" solution like for me. – Ximik Nov 22 '10 at 21:51
  • 2
    The lock file solution is fine - and the socket solution is similar in intent. Big question for you: **Why** does your program crash if there are two copies running? What about if I want to run one copy on my data while Fred wants to run one copy on his data? There isn't a standard built-in mechanism because it is not needed as often as people would like to think. – Jonathan Leffler Nov 22 '10 at 22:05
  • 3
    To add to Jonathan Leffler's comment, the critical resource is the data, not the program. Use a lockfile on the data, not on the program. – mouviciel Nov 22 '10 at 22:38
  • It works with data on special device, but I'll think about this way. Thanks. – Ximik Nov 22 '10 at 22:47

2 Answers2

3

One daemon I wrote opened a UNIX domain socket for regular client-daemon communication. Other instances then checked whether they could connect to that socket. If they could, another instance was currently running. Edit: As noted by @psmears, there's a race condition. The other instances should just try to create that same listening socket. That will fail if it is already in use.

Lock files work more often than that special case. You may create an (empty) file in a well known location and then use file locks, say with fcntl(2) and F_SETLK and F_GETLK to set a lock on that file or determine whether a lock is held. May not work over NFS. Locks are cleared when your process dies, so this should work, and is portable (at least to HP-UX). Some daemons like to dump their pid into that file if they determine that no other instance is currently running.

dennycrane
  • 2,301
  • 18
  • 15
  • 3
    The UNIX domain socket idea is a good one - but rather than trying to connect to the socket, you should try to create another socket with the same name. If that fails due to the address being in use, the daemon is already running. (The reason for this is to avoid a race condition - otherwise it's possible for two of your processes to start at almost exactly the same time - both will try to connect to the socket, which doesn't exist yet; both will succeed, then both will continue running (unless they *also* check/exit when creating the socket - but in that case why do the extra work? :-) ) – psmears Nov 22 '10 at 21:49
  • +1. Good catch. The code I cited is production code and does, in fact, bail if it cannot create the listening socket. – dennycrane Nov 22 '10 at 21:52
  • Thank you for your answer. So seems like I have to use pids. – Ximik Nov 22 '10 at 21:55
1

You can use named sempahores, which is a very standard approach to this problem. Your program calls semctl() to find if there are any active sempahores, then checks to see if you can run. If you find none, then you create the sempahore.

The OS handles the problem of processes being killed off with kill -9 and leaving sempahores. You need to read the man page for semctl and sem_open for your machines to see what that mechanism is.

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51