C++信号处理

注册处理信号

头文件signal.h。

param1:信号的类型。
param2:处理信号事件的回调函数。
void signal(int, void (*callback)(int));

注册了某个信号后,当系统收到这个信号,就会调用回调函数。
这种注册是一次性。意思是,系统调用了一次回调函数后,当这个信号再次触发,系统将不会调用这个回调函数,而是使用默认的处理方法。
示例:

void callback(int tag){	
	cout << "recive signal : " << tag << endl;
} 

int main()
{	
	signal(SIGINT, callback); 	
	while (1){		
		Sleep(500);		
		raise(SIGINT);
	}    
	return 0;
}

效果:控制面板输出一次后,程序自动关闭。

这种注册是不可重复的。意思是,即使你连续重复注册某个信号,实际效果与注册一次相同。
示例:

void callback(int tag){	
	cout << "recive signal : " << tag << endl;
} 

int main()
{	
	signal(SIGINT, callback);	
	signal(SIGINT, callback);	
	signal(SIGINT, callback); 	
	while (1){		
		Sleep(500);		
		raise(SIGINT);
	}    
	return 0;
}

效果:控制面板输出一次后,程序自动关闭。

主动发送信号

param1:信号的类型。
void raise(int)

发送的信号类型必须是系统给出的,不然,运行程序会报错。
示例:

//main()中
raise(1);

报错:未知的信号或错误。
C++信号处理

系统给出的信号类型,在signal.h头文件中查看。

类型 描述
#define SIGINT 2 中断
#define SIGILL 4 非法指令-无效函数镜像
#define SIGFPE 8 错误的算术运算,比如除以零或导致溢出的操作
#define SIGSEGV 11 非法访问内存
#define SIGTERM 15 通过kill发送到本进程的终止信号
#define SIGBREAK 21 Ctrl-Break sequence
#define SIGABRT 22 程序的异常终止,如调用 abort。
#define SIGABRT_COMPAT 6 SIGABRT 兼容其它平台, 类似于 SIGABRT

连续收发同一信号示例

可以看到,发送周期为500毫秒,处理函数周期为1000毫秒。而控制台打印是连续的,所以,raise()是阻塞的。

void callback(int tag){	
	cout << "recive signal : " << tag << endl;	
	Sleep(1000);	
	signal(SIGINT, callback);
} 

int main()
{	
	signal(SIGINT, callback); 	
	while (1){		
		Sleep(500);		
		raise(SIGINT);		
		cout << "send signal : " << SIGINT << endl;	
	}     
	return 0;
}

输出结果,打印连续。
C++信号处理

一个疑问

写了个示例,第一次按Ctrl+C,控制台没输出。通过打断点,发现根本没进回调函数。第二次按Ctrl+C,弹出警告窗口。
期望的效果是按下Ctrl+C,控制台有打印。难道这个示例在linux上才能有效果?
当前环境:win7 + VS2015。

代码:

void callback(int tag){	
	cout << "recive signal : " << tag << endl;
} 

int main()
{	
	signal(SIGINT, callback); 	
	while (1){		
		Sleep(500);	
	}     
	return 0;
}