Implementation of Single Process Control for Linux C Background Service Program

  • 2021-07-06 12:11:15
  • OfStack

Introduction

Usually, the background server program must have only one process, so how to have a single process?

This example uses the flock function to lock the pid file logged at/var/run/myserver. pid

If the lock is not normal, it means that the background service process is already running, and then directly report an error and exit If the lock is successful, it means that the background service process is not running, and the process can be enabled normally at this time

Background service single process control

Don't say much in detail, look at the code directly


#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-- Is 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 
  // LOCK_SH  Establish a shared lock. Multiple processes can be aligned at the same time 1 File sharing lock. 
  // LOCK_EX  Create a mutex lock. 1 File at the same time only 1 Mutex lock. 
  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;
  }

  //  Successful locking proves that the service is not running 
  //  Do not close or unlock the file handle 
  //  When the process exits, it is automatically unlocked 
  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());

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

  return 0;
}

int main(void)
{

  // Process single instance run 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;
}

Running result

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


[root@lincoding 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 this process. ps auxf grep myserver shows that mysever Process 1 is running directly


[root@lincoding singleprocess]# cat /var/run/myserver.pid 
6965
[root@lincoding singleprocess]# 
[root@lincoding 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
[root@lincoding singleprocess]# 

At this time, run the myserver program again, at this time will report an error exit, because the myserver program is already running, can not start another process, thus achieving the background service program single process control


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

Related articles: