如果生成子进程,则对单个实例程序使用文件锁会失败
using file lock for a single instance program fails if spawn child process
我需要在 Linux 中有一个单实例程序。也就是说,如果有人试图 运行 新实例应该打印一条消息并退出的程序。目前我有这样的锁定机制:
main() {
// init some stuff...
// set or check lock
auto pidFile = open("/var/run/my-app.lock", O_CREAT | O_RDWR, 0666);
auto rc = flock(pidFile, LOCK_EX | LOCK_NB);
if(rc) {
if(errno == EWOULDBLOCK) {
cout << "Program is already running!\n";
exit(0);
}
}
// do other stuff or the main loop
// when the loop ends by sigkill or sigterm or ...
exit(0);
}
问题是,如果我使用 int system(const char *command);
执行任何生成子进程的操作,并且在某个时候,有人使用“kill”来结束该程序,子进程将保持活动状态并且锁不会被删除因此阻止我的应用程序再次 运行。
这个缺点有解决办法吗?
您需要 O_CLOEXEC
作为 open()
的标志。那么句柄就不会在子进程中打开了。
system()
最终调用 exec()
,这是加载新进程二进制文件的方式。
我需要在 Linux 中有一个单实例程序。也就是说,如果有人试图 运行 新实例应该打印一条消息并退出的程序。目前我有这样的锁定机制:
main() {
// init some stuff...
// set or check lock
auto pidFile = open("/var/run/my-app.lock", O_CREAT | O_RDWR, 0666);
auto rc = flock(pidFile, LOCK_EX | LOCK_NB);
if(rc) {
if(errno == EWOULDBLOCK) {
cout << "Program is already running!\n";
exit(0);
}
}
// do other stuff or the main loop
// when the loop ends by sigkill or sigterm or ...
exit(0);
}
问题是,如果我使用 int system(const char *command);
执行任何生成子进程的操作,并且在某个时候,有人使用“kill”来结束该程序,子进程将保持活动状态并且锁不会被删除因此阻止我的应用程序再次 运行。
这个缺点有解决办法吗?
您需要 O_CLOEXEC
作为 open()
的标志。那么句柄就不会在子进程中打开了。
system()
最终调用 exec()
,这是加载新进程二进制文件的方式。