我需要测量处理异常所需的时间并调用信号处理程序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;
}
任何人都知道我需要如何处理这个信号?我完全迷失了这个
答案 0 :(得分: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( "%d\n", caught );
}
全局变量caught
用于指示异常被捕获。初始值为33.信号处理程序将其设置为42.程序末尾的printf
显示最终值。它应该打印42表示该信号被捕获。
env
和sigsetjmp
函数使用全局变量siglongjmp
来保存寄存器和堆栈的副本。
if (sigsetjmp(env,1) == 0)
最初将为真,并且将尝试除法。但是,当调用处理程序时,siglongjmp
将使程序的行为就像sigsetjmp
返回1
一样,并且将跳过除法。
这允许程序移过分区,并在最后执行printf
。