Linux flock实现单进程启动
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
bool single_proc_running(const char *process_name)
{
char lock_file[128];
snprintf(lock_file, sizeof(lock_file), "/var/tmp/%s.lock", process_name);
int lock_fd = open(lock_file, O_CREAT|O_RDWR, 0644);
if (-1 == lock_fd)
{
fprintf(stderr, "Fail to open lock file(%s). Error: %s\n",lock_file,strerror(errno));
return false;
}
if (0 == flock(lock_fd, LOCK_EX | LOCK_NB)) {
return true;
}
close(lock_fd);
lock_fd = -1;
return false;
}
extern int Start();
int main()
{
if(!single_proc_running("server"))
{
cout << "single server process can be created." << endl;
return 0;
}
//执行任务
int i = Start();
if (i != 0)
{
cout << "Server Running failed." << endl;
}
return 0;
}
flock是建议性锁,不具备强制性。一个进程使用flock将文件锁住,另一个进程可以直接操作正在被锁的文件,修改文件中的数据,原因在于flock只是用于检测文件是否被加锁,针对文件已经被加锁,另一个进程写入数据的情况,内核不会阻止这个进程的写入操作,也就是建议性锁的内核处理策略。
第二个参数:
LOCK_SH,共享锁,多个进程可以使用同一把锁,常被用作读共享锁;
LOCK_EX,排他锁,同时只允许一个进程使用,常被用作写锁;
LOCK_UN,释放锁;
进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB(非阻塞)参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误,errno错误码为EWOULDBLOCK。
flock锁的释放可调用LOCK_UN参数来释放文件锁,也可以通过关闭fd的方式来释放文件锁,意味着flock会随着进程的关闭而被自动释放掉。当打开文件的所有描述符被关闭时或者进程结束时,锁会自动释放,也可以手动释放(flock与fcntl不同,fcntl关闭一个文件描述符则锁释放,例如dup)
强制性加锁可以参考fcntl中的F_SETLK属性(不等待),F_SETLKW(等待)
fcntl函数设置的第三个参数的结构体如下:
struct flock
{
...
short l_type;/* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) */
}
以下为简易流程:
int checkproc(char* pfile)
{
if (pfile == NULL)
{
return -1;
}
int lockfd = open(pfile,O_RDWR);
if (lockfd == -1)
{
return -1;
}
int iret = flock(lockfd,LOCK_EX|LOCK_NB);
if (iret == -1)
{
return -1;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示