在程序设计中,一个程序通常可以被多次执行,即在未结束的情况下可启动多个实例。例如聊天软件 QQ 允许用户同时登录多个账户,很多游戏也支持在同一台电脑上同时登录多个账号,只要系统性能允许。
但某些类型的程序,允许多个实例运行会导致资源冲突或数据不一致,此时就需要单例模式运行——确保一个程序在任意时刻只能有一个实例在运行,直到该实例完全结束。这在以下场景尤为重要:
- 守护进程:通常只需运行一个实例,避免资源浪费和潜在错误。
- 配置管理:确保配置文件的唯一性,避免多个实例并发修改。
- 资源管理:如数据库连接池通常只需一个实例集中管理连接,避免创建过多连接导致性能问题。
在 SoC 程序中实现单例模式运行,主要有两种方法:使用文件存在性判断、使用文件锁。
1、使用文件存在性判断
这种方法简单易行,基本思路是:创建一个特定文件作为锁标志,程序启动时检查该文件是否存在——若存在表示已有实例在运行则退出;若不存在则创建该文件并继续执行,程序结束时删除该文件。
实现要点:程序开始时用 stat() 或 access() 检查文件;用 open() 创建文件;程序结束时用 remove() 或 unlink() 删除文件。选取文件名要注意唯一性,避免与其他文件冲突。
#include
#include
#include
#include
int main() {
const char *lock_file = "/tmp/soc_program.lock";
if (access(lock_file, F_OK) != -1) {
fprintf(stderr, "程序已经在运行。");
return 1;
}
FILE *file = fopen(lock_file, "w");
if (file == NULL) {
perror("无法创建锁文件");
return 1;
}
printf("程序正在运行...");
sleep(10);
fclose(file);
remove(lock_file);
return 0;
}2、使用文件锁
文件锁是更为可靠的方法:打开一个特定文件作为锁文件,用 flock() 获取独占锁,若获取失败则提示已有实例并退出。
#include
#include
#include
#include
#include
int main() {
const char *lock_file = "/tmp/soc_program.lock";
int fd = open(lock_file, O_WRONLY | O_CREAT, 0666);
if (fd < 0) return 1;
if (flock(fd, LOCK_EX | LOCK_NB) != 0) {
close(fd);
return 1;
}
dprintf(fd, "%d\n", getpid());
sleep(10);
close(fd);
return 0;
}代码要点:open() 打开锁文件;flock() 获取独占且非阻塞的锁;dprintf() 写入当前进程 ID;正常结束时关闭文件释放锁。
通过以上方法,SoC 程序可以确保同一时刻只有一个进程运行,减少资源争用和潜在错误。








单例模式两种实现对比清楚,文件锁比单纯判断文件存在性靠谱多了。
守护进程和数据库连接池这种确实该用单例,防止多开出错。
代码注释也细,适合直接照着搬到项目里用。