Only one process (Singleton)

There are several ways to prevent two or more of the same processes from running at the same time. Typical methods include using socket binds, using semaphores, and file locking. The following simple example shows file locking to run only one process.

C/C++


#include <sys/file.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <stdbool.h>

bool singleton()
{
        struct flock lock;
        int pid_file = open("/tmp/whatever.pid", O_CREAT | O_RDWR, 0666);
        if(pid_file < 0){
                fprintf(stderr, "pid file open error\n");
                return false;
        }
        fprintf(stderr, "pid file lock start\n");

        lock.l_type = F_WRLCK;
        lock.l_start = 0;
        lock.l_whence = SEEK_SET;
        lock.l_len = 0;

        int ret = fcntl (pid_file, F_SETLK, &lock);
        if(ret == -1){
                fprintf(stderr, "pid file lock error\n");
                return false;
        }
        fprintf(stderr, "pid file lock success\n");
        return true;

}

int main(int argc, char *argv[])
{
        if(false == singleton()){
                exit(1);
        }
        //You are the only one process. Do what you want to do
        sleep(10);
        return 0;
}



You don't have to close pid_file (file descriptor). When the process ends, the operating system automatically closes all opend files. And the next process can open and lock the file(whatever.pid)

Be careful : If you use a F_SETLKW parameter in the fcntl function, the process waits for the process that locked the file to terminate. This situation may not be what you want.


Python

In Python, it can be implemented using a pid file as in the C/C++ example above.
However, it can be implemented simply by installing the tendo package.

pip3 install tendo

And it can be implemented simply as follows:

from tendo import singleton
me = singleton.SingleInstance()

# Your code Here !


You can also create and use a pid file directly by installing the pidfile package as follows.

pip3 install python-pidfile

And at the beginning of the Python code, add the following code:

import pidfile
import time, sys

print('Starting process')
try:
    with pidfile.PIDFile("/var/run/myprocess.pid"):
        print('Process started')
        #your code Here
except pidfile.AlreadyRunningError:
    print('Already running.')
    sys.exit(1)

time.sleep(60)

print('Exiting')

There is one thing to note when using python-pidfile. As in the example above, you should always use the "with" syntax.







댓글

이 블로그의 인기 게시물

MQTT - C/C++ Client

RabbitMQ - C++ Client #1 : Installing C/C++ Libraries

C/C++ - Everything about time, date