在c++中确定系统停止
Determine system halt in c++
好吧,我正在编写一个用c++编写的程序,它作为守护进程运行。它主要针对Linux用户,但我希望包括Windows(作为服务运行)和Mac用户。
我希望守护进程在手动关闭时进行日志记录。但是,它不应记录系统因系统停止或重新启动而导致的关闭。
目前,我已经屏蔽了所有信号,并使用sigaction()实现了某种处理。在记录关闭之前,一个函数还检查系统的运行级别,如果是0,1 0r 6,则会省略记录。检查运行级别的方法是运行命令"runlevel"并处理输出。
我的问题是运行级别并不总是我所期望的。我运行的是Ubuntu,当像往常一样登录时,我处于运行级别2,重新启动时也是如此。当停止时,我有时从"runlevel"中得不到任何输出。不同的Linux发行版都使用自己的运行级别,所以它对于可移植性来说不是最佳的。
那么,有没有更好的方法来确定系统是否正在停止?此外,是否有更好的方法来捕捉中断,例如通过异常处理等?
如果这里有任何帮助的话,我会粘贴一段代码。用c++编写,使用Poco c++库。
void MainApplication::signalHandler(int sig) {
#if defined(POCO_OS_FAMILY_UNIX)
switch(sig) {
case -1:
struct sigaction act;
act.sa_handler = signalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0); //Better way to do this?
sigaction(SIGQUIT, &act, 0);
sigaction(SIGKILL, &act, 0);
sigaction(SIGTERM, &act, 0);
sigaction(SIGHUP, &act, 0);
sigaction(SIGSTOP, &act, 0);
sigaction(SIGTSTP, &act, 0);
sigaction(SIGCONT, &act, 0);
sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0);
break;
case SIGINT:
case SIGQUIT:
case SIGTSTP:
case SIGHUP:
case SIGKILL:
case SIGTERM:
//Log Shutdown!
if (!isHalting())
_instance->_database->logBypass(BYPASS_SHUTDOWN);
terminateNicely(true);
break;
case SIGCONT:
//Continued, means stopped
break;
case SIGUSR1:
//Resetting Net Responsibility
_instance->uninitialize();
_instance->initialize(*_instance);
break;
case SIGUSR2:
//Other action or just mask it
break;
default:
//Caught signal
break;
}
#endif
}
bool MainApplication::isHalting() {
#if defined(POCO_OS_FAMILY_UNIX)
string cmd("runlevel");
vector<string> args;
Poco::Pipe outPipe;
ProcessHandle ph = Process::launch(cmd, args, 0, &outPipe, 0);
ph.wait();
Poco::PipeInputStream istr(outPipe);
stringstream ss;
Poco::StreamCopier::copyStream(istr, ss);
int runlevel;
ss.seekg(-2, ios::end);
ss >> runlevel;
return (runlevel == 0 || runlevel == 1 || runlevel == 6);
#else
return false;
#endif
}
我最终走了另一条路来解决这个问题。现在我正在读取计算机的启动历史记录,并将其与软件的历史记录进行比较,看看计算机是在没有软件的情况下启动还是停止。这已经足够了,而且可能会更加准确。
用于确定Linux中引导历史记录的命令是
$ last reboot
相关文章:
- C++,系统无法执行指定的程序
- 在UNIX系统中使用DIR查找文件的字节大小
- 错误处理.将系统错误代码映射到泛型
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在C++游戏中与库存系统作斗争
- 文件系统:复制功能的速度秘诀是什么
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 在gtest.中使用fff.h模拟系统API
- 如何制作无限制照明系统
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 如何传递多个 std::文件系统选项?
- 遍历顺序由 std::文件系统directory_iterator给出
- C++系统找不到指定的文件错误
- 系统参数信息A 与 SPI_GETMOUSE 返回 0
- libstdc++ 文件系统中未初始化的用法?
- 如何在ECS框架中更新组件数据和通知系统
- boost::文件系统::recursive_directory_iterator多线程安全
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- SFML 碰撞永远不会在我的系统中注册