通常情况下一个程序可以被多次执行,也就存在多个相同的进程。有时候我们有些全局资源只允许单进程访问,为了不让进程多起,要实现进程在一台机器上只能有一个实例的方法。
经查找,可以使用flock的方式,建一个lock file,让程序执行前先检查是否有执行中的实例,即对文件加锁。
single_program.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
int main()
{
int lock_file = open("/tmp/single_proc.lock", O_CREAT|O_RDWR, 0666);
int rc = flock(lock_file, LOCK_EX|LOCK_NB);
if (rc)
{
if (EWOULDBLOCK == errno)
{
printf("该实例已经运行!\nExit...");
}
}
else
{
char buffer[64];
sprintf(buffer, "pid:%d\n", getpid());
write(lock_file, buffer, strlen(buffer));
printf("已启动新实例,输入任何字符退出...\n");
scanf("%s",buffer);
printf("Exit\n",buffer);
close(lock_file); // 不要忘记释放文件指针
}
exit(0);
}
运行结果
[root@centos6 data]# gcc single_program.c -o single_program
[root@centos6 data]# ./single_program
已启动新实例,输入任何字符退出。
以上程序会阻塞等待,然后新开一个终端,同样执行该程序
[root@centos6 data]# ./single_program
该实例已经运行,退出!
[root@centos6 data]#
可以看到程序一启动就退出了。查看锁文件
[root@centos6 data]# cat /tmp/single_proc.lock
pid:7162
表明现在已经加了一个全局的锁文件,无法在启动新进程了。查看已经启动的进程。
[root@centos6 data]# ps -ef|grep -v grep|grep single_program
root 7162 6521 0 22:13 pts/0 00:00:00 ./single_program
确实只有一个进程,这样的方式我们可以用在一些只允许一台机器上启动单进程的特殊场景。