좋아요. 그래서 나는 데몬으로 실행중인 C++로 작성된 프로그램에서 작업하고 있습니다. 그것은 주로 리눅스 사용자를 겨냥하고 있지만 Windows (서비스로 실행 중)와 Mac 사용자를 포함시키고 싶습니다.C++에서 시스템 중지 확인
데몬이 수동으로 종료 될 때마다 기록하도록합니다. 그러나 이 아닌 시스템 종료 또는 재부팅으로 인해 시스템이 로그를 종료해야합니다.
현재 모든 신호를 마스크 처리하고 sigaction()을 사용하여 일종의 처리를 구현했습니다. 시스템 종료를 로깅하기 전에 함수는 시스템의 런레벨도 확인하고, 0, 1 0 6이면 로깅이 생략됩니다. 런레벨을 검사하는 방법은 "runlevel"명령을 실행하고 출력을 처리하는 것입니다.
내 문제는 런레벨이 항상 내가 기대하는 것만은 아니다. 나는 우분투를 실행하고 있는데 평상시처럼 로그인 할 때 나는 런레벨 2에 있고 재부팅 할 때도 마찬가지다. 멈 추면 가끔 "런레벨"의 출력으로 얻지 못합니다. 다른 리눅스 배포판은 자체 런레벨을 사용하기 때문에 이식성이 좋지 않습니다.
그래서 시스템이 정지하는지 확인하는 더 좋은 방법이 있습니까? 또한 중단을 잡는 더 좋은 방법이 있습니까? 예 : 예외 처리 등을 통해?
여기에 도움이된다면 코드 스 니펫을 붙여 넣습니다. C++로 작성되었으며 Poco C++ libraries을 사용합니다.
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
}
왜 당신이 당신의 서비스에 대해 서로 다른 행동이'SIGTERM' 및 전체 시스템 인 종료와 함께 종료 될해야합니까? –
그것은 프로그램의 개념에 놓여 있습니다. 항상 실행되도록 설계되었습니다. 그러나 종료해야하는 경우 특정 전자 메일 주소로보고해야합니다. 컴퓨터가 부팅되고 재부팅 된 모든 시간에 대한 통계를 원하지는 않지만 사용자가 수동으로 중단했는지 확인하고 싶습니다. 희망이 어떤 의미가있어 :) – roggan87
예를 들어 가지고 sysadmin. 자신의 서버에서 프로그램을 업그레이드 (또는 사용중인 데이터베이스를 중지하십시오!)하면 "항상 실행되도록"하는 관점이 다를 수 있습니다. 그래서 그에게 그의 시스템을 관리 할 수있는 능력을 남겨주세요. –