应用单例启动实现(采用文件锁方式)

应用单例启动(采用文件锁方式)


有时候我们的应用程序在系统中可能只允许启动一个(比如服务程序),怎么实现这种需求呢?

思想:我们可以采用文件锁的方式,因为通过文件锁,可以保证同一时刻只有一个应用能占得文件资源,获取锁成功的可以执行,如果被其他进程占用时就不能执行。

准备:有了思路后,剩下就是怎么操作设置文件锁了。用到网络锁,就不可避免要使用fcntl函数。

  • fcntl函数,调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的的各种属性
  • fcntl函数介绍如下:
    fcntl函数

fcntl的返回值与命令有关。如果出错,所有命令都返回-1,同时错误码记录在errno中;如果成功则返回某个其他值。下列四个命令有特定返回值:F_DUPFD、F_GETFD、F_GETFL、F_GETOWN.第一个返回新的文件描述符,接下来的两个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。
上述我们用到的是F_SETLK。如果锁被其他进程占用导致无法设定锁,则返回-1,errno错误代码为EACCESEAGAIN

当fcntl用于管理文件记录锁的操作时,第三个参数指向一个struct flock *lock的结构体,如下:

struct flock
{
    l_type;    /*锁的类型*/
    l_whence;  /*偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END*/
    l_start;     /*加锁的起始偏移*/
    l_len;    /*上锁字节*/
    l_pid;   /*锁的属主进程ID */
}; 

flock结构体

如果要加锁整个文件,通常的方法是将l_start 设置为0,l_whence 设置为SEEK_SET,l_len设置为0.

实现:基本的一些知识清楚了之后,就要写代码实现了,下面的代码是我写的一个小demo。
主要部分:

	struct flock flc;
	flc.l_type = F_WRLCK;  // write lock
	flc.l_start = 0;
	flc.l_whence = SEEK_SET;
	flc.l_len = 0;		   //lock the whole file
	if(fcntl(fd, F_SETLK, &flc) < 0)
	{
		if(errno == EACCES || errno == EAGAIN)
		{
			printf("This process already exist!\n");
			return 0;
		}
		perror("Set FileLock Failed!");
		exit(1);
	}
	printf("Process will run!\n");

代码地址:https://github.com/JeffCheng95/C-C-Demo/tree/master/应用单例运行

发布了87 篇原创文章 · 获赞 213 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/buknow/article/details/102728238