在Linux 系统中/var/run下有很多以pid结尾的文件,这个其实是为了保证程序以单例模式运行而设计的。程序在启动后,首先打开(如果没有则创建)/var/run/xx.pid,然后尝试去设置文件锁,如果成功,则将程序的进程ID写入该文件,写入后注意不要关闭文件或解锁;如果加锁失败,表明程序已经有一个进程在运行了,则退出此次启动。此机制在一些程序尤其是服务器程序中很常见,例如sip 服务器kamailio中就是这样保证程序以单例模式运行的。
注:程序退出后,文件锁自动解锁。
<span style="font-size:18px;">#include <stdio.h> #include <string.h> #include <fcntl.h> #include <stdlib.h> #define DEFAULT_FILE "/var/run/test.pid" int main(int argc, char *argv[]) { int fd = -1; char buf[32]; fd = open(DEFAULT_FILE, O_WRONLY | O_CREAT, 0666); if (fd < 0) { perror("Fail to open"); exit(1); } struct flock lock; bzero(&lock, sizeof(lock)); if (fcntl(fd, F_GETLK, &lock) < 0) { perror("Fail to fcntl F_GETLK"); exit(1); } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; if (fcntl(fd, F_SETLK, &lock) < 0) { perror("Fail to fcntl F_SETLK"); exit(1); } pid_t pid = getpid(); int len = snprintf(buf, 32, "%d\n", (int)pid); write(fd, buf, len); //Write pid to the file printf("Hello world\n"); while(1); return 0; } </span>
编译:
gcc -o test test.c
运行:
1. 打开终端: ./test
cat /var/run/test.pid
23409
2. 打开另一终端:./test,打印错误如下
Fail to fcntl F_SETLK: Resource temporarily unavailable
表示程序已经有实例运行