A process is an instance of a program. A program can be instanced several times, that is, several processes can be created with the same executable code loaded. I would like to quote a line from Understanding the Linux Kernel by Daniel P. Bovet and Marco Cesati:
It is important to distinguish programs from processes; several processes can execute the same program concurrently, while the same process can execute several programs sequentially.
Basically, this means that while a program can be run in several instances, a single instance can only load one executable code at a time. So, starting from there, we could say that nothing prevents a program from running into multiple instances, because there is absolutely no reason to forbid it. Of course, these processes will not share anything but their execution code. Memory pages, file descriptors (which may concern identical files), and so on... are completely independent from one process to another.
Another point seems important to me when it comes to Unix-like systems (same book) :
Unix-like operating systems adopt a process/kernel model. Each process has the illusion that it’s the only process on the machine, and it has exclusive access to the operating system services.
Indeed, this is why Unix systems are multiprocessing/multiprogramming, or at least, it is the policy upon which this feature is based. So, due to this very fact, there is no way for a process to natively know that another process, running the exact same code, is waiting, or working on another CPU.
However, each process knows one thing: the system is being run by the kernel, and the kernel's services are at the process' disposal for all the time it'll spend working on a CPU. Thanks to this, it is possible for a process to query the kernel about other processes running as instances of the same executable. The first solution that comes to my mind is to read the
/proc virtual filesystem. This FS acts like an interface between the user/application and the kernel (since these files represents kernel structures and data). In this filesystem, each process is given a directory (named with its PID), and within this directory, you will find a link called
exe. For instance, here is my
bash process' directory, PID 22343:
lrwxrwxrwx /proc/22343/exe -> /bin/bash*
Now, by browsing the filesystem, you will be able to find processes which are running the same executable code, that is, processes for which the
exe link targets the same executable file.
However, since all Unix systems do not implement
/proc the same way, developers aim to use a more portable solution, which relies on something pretty much all Unix systems understand: regular files. This is what
.pid files are usually here for.
Most of the time, you will find these files in
/run. For instance:
These files are created by the application to which they belong, and used as markers of whether or not an instance of a program is running. Typically, the content of this file is simply made of the PID of the running process. In this case, I have a
acpid process running, with PID 1503, and that's exactly what's in the PID file.
Now, since all processes of the same program share the same execution code, they share their constants (at least, their values). For this reason, if each instance knows where to look for the PID file, programming a single-instance program is quite easy:
if (the pid file exists) then
send a signal to the running process or just bring it on the foreground
exit since the work is going to be handled by the already-running process
actually start the program, the first instance
Using signals in the first case is the behaviour I have seen the most, however, if your application uses some more sophisticated IPC (sockets, message queues, ...), you could use it to inform it that the user has requested something that it needs to do.