我需要测量处理异常和调用信号处理程序100,000次所需的时间。我需要使用signal()
系统调用来注册SIGFPE
的处理程序函数,然后我需要引起除以0的错误。
我现在只有一个骨架,我不确定我应该如何处理这个信号。到目前为止,我计划调用gettimeofday()
,然后进入一个for循环100k次,调用signal()
,然后进入另一个gettimeofday()
,以结束时间,然后取总运行时间,并在这100k次调用中取平均值。
#include <signal.h>
#include <sys/time.h>
void handle_sigfe(int signum)
{
//unsure how to handle the signal to keep the loop running for 100k times
}
double time_in_milli (struct timeval t){ //for time conversion
return (((t.tv_sec*1000000+t.tv_usec)*1000)/1000000);
}
int main(int argv, char ** argv)
{
int x =5;
int y = 0;
int z = 0;
signal(SIGFPE, handle_sigfpe);
z = x/y;
return 0;
}
谁有任何线索,我需要如何处理这个信号?
被零除异常调用您安装的处理程序。当处理程序返回时,处理器返回到除法指令并再次尝试。结果是一个无限循环。为了防止这种情况,您可以使用sigsetjmp
和siglongjmp
例程。
当你调用sigsetjmp
时,它返回0。但是,当调用siglongjmp
时,程序的行为就像sigsetjmp
返回siglongjmp
提供的值一样。因此,您可以使用if
语句来执行除法或根据sigsetjmp
的返回值跳过除法。
如果这太令人困惑,希望下面的例子将澄清问题。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
static sig_atomic_t caught = 33;
static sigjmp_buf env;
void action( int unused )
{
caught = 42;
siglongjmp( env, 1 );
}
int main( void )
{
if ( signal( SIGFPE, action ) == SIG_ERR ) {
perror( "signal failed" );
return 1;
}
int x = 1;
int y = 0;
int z;
if ( sigsetjmp( env, 1 ) == 0 )
z = x / y;
printf( "%dn", caught );
}
全局变量caught
用于指示异常被捕获。初始值为33。信号处理程序将其设置为42。程序末尾的printf
显示最终值。它应该打印42来表示该信号被捕获。
全局变量env
被sigsetjmp
和siglongjmp
函数用来保存寄存器和堆栈的副本。
if (sigsetjmp(env,1) == 0)
初始值为true,然后尝试除法。但是,当调用处理程序时,siglongjmp
将使程序表现为好像sigsetjmp
返回1
,并且除法将被跳过。
这允许程序越过除法,并在最后执行printf
。