introduce

Usually background server programs must have and only have one process, so how to single process?

This example locks the pid file of / var/run/myserver.pid record through the flock function

  • If the lock is not normal, it means that the background service process is already running, then it will exit directly by error.
  • If the lock is successful, the background service process is not running, then the process can be activated normally.

Background Service Program Single Process Control

Let's not go into details, just look at the code.

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

#define  PID_BUF_LEN   (20)
#define  RUN_PID_FILE  "/var/run/myserver.pid"

//Service Process Single Instance Running
//Return value: 1 -- running, 0 -- not running, 1 -- error
int server_is_running()
{
    int fd = open(RUN_PID_FILE, O_WRONLY|O_CREAT);
    if(fd < 0)
    {
        printf("open run pid err(%d)! %s\n", errno, RUN_PID_FILE);
        return -1;
    }
     
    // Lock up
    // LOCK_SH establishes shared locking. Multiple processes can lock the same file at the same time.
    // LOCK_EX establishes mutex locking. A file has only one mutex lock at the same time.
    if(flock(fd, LOCK_EX|LOCK_NB) == -1)
    {
        //If the lock is not added, the service is running and locked.
        printf("server is runing now! errno=%d\n", errno);
        close(fd);
        return 1;
    }

    // Lock successfully to prove that the service is not running
    // Do not close or unlock the file handle
    // The process exits and automatically unlocks
    printf("myserver is not running! begin to run..... pid=%ld\n", (long)getpid());

    char pid_buf[PID_BUF_LEN] = {0};
    snprintf(pid_buf, sizeof(pid_buf)-1, "%ld\n", (long)getpid());

    // Write process pid to / var/run/myserver.pid file
    write(fd, pid_buf, strlen(pid_buf));

    return 0;
}

int main(void)
{

    //Process Single Instance Running Detection
    if(0 != server_is_running())
    {
        printf("myserver process is running!!!!! Current process will exit !\n");
        return -1;
    }

    while(1)
    {
        printf("myserver doing ... \n");
        sleep(2);
    }

    return 0;
}

Operation result

Running the program, we can see that the process pid is 6965

[[email protected] singleprocess]# ./myserver 
server is not running! begin to run..... pid=6965
myserver doing ... 
myserver doing ... 
myserver doing ... 
myserver doing ... 
myserver doing ... 
myserver doing ... 
myserver doing ... 
myserver doing ... 

/ var/run/myserver.pid also records the PID number of the process. ps auxf | grep myserver knows that the mysever process has been running

[[email protected] singleprocess]# cat /var/run/myserver.pid 
6965
[[email protected] singleprocess]# 
[[email protected] singleprocess]# ps auxf | grep myserver
root      6965  0.0  0.0   3924   460 pts/0    S+   00:32   0:00  |       \_ ./myserver
root      9976  0.0  0.0 103256   856 pts/1    S+   00:35   0:00          \_ grep myserver
[[email protected] singleprocess]# 

At this time, the myserver program is run again, and then an error will be reported and exited, because it is detected that the myserver program is already running, and can not start another process, thus achieving the single process control of the background service program.

[[email protected] singleprocess]# ./myserver 
server is runing now! errno=11
myserver process is running!!!!! Current process will exit !