std::signal은 signal.h 헤더 내부에 정의된 신호를 받았을 때, OS에서 진행되고 있는 서비스를 중단시키고 신호 핸들러에 정의된 기능들을 수행할 수 있게 해준다.

예제 1


GeeksForGeeks에서 보여주는 간단한 예제는 아래와 같다.

For loop에서 계속 "Hello GeeksforGeeks..."라는 스트링을 cout 출력을 해주다가, ctrl+c를 눌러서 종료하였을 때, SIGABRT 신호를 포착해 signal_handler() 함수를 강제 실행한다. 그러면 기존의 스트링이 아닌 새로운 "The interrupt signal is ("... 가 출력되고, 프로그램을 종료한다.

#include <iostream> 
#include <csignal> 
using namespace std; 
  
void signal_handler( int signal_num ) { 
   cout << "The interrupt signal is (" << signal_num << "). \\n"; 
     
   // terminate program   
   exit(signal_num);   
} 
  
int main () { 
   signal(SIGABRT, signal_handler);   
  // register signal SIGABRT and signal handler   
  
   while(true) 
      cout << "Hello GeeksforGeeks..." << endl; 
   return 0; 
}

시그널 정보


signal.h 헤더 내부에는 아래와 같은 pre-defined signal이 있다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a3b77e07-b3be-46b3-9bee-0a6dfc7e514e/Untitled.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d9cd09c0-9f30-4dc5-9a30-025c7840bf56/Untitled.png

std::raise(_signal)을 사용해서 강제로 시그널을 보내는 방법도 있다.

내가 쓰는 방법


void saveExperimentDataCallback(int registered_signal)
{
	// save all the data until now
}

int main()
{
	std::signal(SIGINT, saveExperimentDataCallback);

	config(_cfg)
	initExperiment();
	
	while (true)
	{
		runExperiment();
	}
}

나는 실험할 때 아래와 같은 방식으로 std::signal을 사용할 것 같다.

실험을 돌리면서 모니터링 하다가 내가 예상하지 못한 결과를 보았을 때, sequence를 끝까지 돌리지 않고 아마 그 자리에서 프로그램을 종료할 것이다. 이 때, SIGINT를 통해 프로그램 종료가 interrupt 되고, 그때까지의 정보를 모두 저장하고 종료하게 만들 수 있다.