在有或没有 sigsetjmp 的情况下使用 sigaction

Using sigaction with or without sigsetjmp

我有一个练习,我必须为此实现一个函数,该函数将一个单参数函数指针 fun、一个指向由所述指针指向的函数的参数 parameter 和一个整数 period。如果函数 fun 的执行指向 parameter 作为参数在 period 秒之前终止,则此函数将 return 为 1,否则为 0。

这两个解是否等价?

static struct sigaction sa, old;
static jmp_buf env;

static void myalarm(int sig)
{
  printf("alarm!\n");
  siglongjmp(env,1);
}

int execution_time_limit( void (*fun)(void *), void *parameter, int period)
{
  sa.sa_handler = myalarm;
  sa.sa_flags = 0; 
  sigemptyset(&sa.sa_mask);
  sigaction(SIGALRM, &sa, &old);

  alarm(period);
  if(sigsetjmp(env,1) == 0) {
    fun(parameter);
    sigaction(SIGALRM, &old, NULL);
  }
  else
    return 0;
 return 1;
}

并且:

static struct sigaction sa, old;
static jmp_buf env;
int ret = 0;

static void myalarm(int sig)
{
  printf("alarm!\n");
  ret = 1;
}

int execution_time_limit( void (*fun)(void *), void *parameter, int period)
{
  sa.sa_handler = myalarm;
  sa.sa_flags = 0; 
  sigemptyset(&sa.sa_mask);
  sigaction(SIGALRM, &sa, &old);

  alarm(period);
  fun(parameter);
  sigaction(SIGALRM, &old, NULL);
  return ret;
}

我会说是,但我想澄清我可能有的任何疑问。

这些不一样。

在第一个例子中,如果触发了警报,fun由于调用了siglongjmp而没有正常退出。在第二个示例中,警报将为 return 值设置标志,但 fun 将继续 运行 完成。

此外,您这里有一个错误:

  if(sigsetjmp(env,1) == 0) 
    fun(parameter);
    sigaction(SIGALRM, &old, NULL);
  else
    return 0
  return 1;

您缺少围绕 ifelse 块的大括号,并且缺少第一个 return 之后的 ;。另外,我相信根据您对函数应该做什么的描述,您混淆了 return 值。

固定码:

  if(sigsetjmp(env,1) == 0) {
    fun(parameter);
    sigaction(SIGALRM, &old, NULL);
  } else {
    return 1;
  }
  return 0;