为什么不能调用函数信号返回的函数(信号处理程序)?

时间:2019-03-28 04:33:11

标签: c signals

弄清楚signal函数的签名后,我修改了https://en.cppreference.com/w/c/program/signal给出的示例。

但是为什么我不能调用signal返回的函数(信号处理程序),却可以称其为direclty呢?


void (*signal( int sig, void (*handler) (int))) (int);

signal函数返回一个指向函数的指针,即void (*)(int)

  

返回值

     

上一个信号处理程序(成功时)或SIG_ERR(失败)(在某些实现中可以禁用设置信号处理程序)。

#include <signal.h>
#include <stdio.h>

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1(3);  //Get signal SIGSEGV and failed
//    signal_handler(3); //OK
    raise(SIGINT);

}

我知道这看起来像是一个毫无意义的问题,但要点是,f1指向signal_handler,所以调用f1(3)就像调用signal_handler(3)一样,我不明白为什么后者可以,但是前者为什么不可以,我认为在这两个调用函数语句之间应该没有“技巧”。

2 个答案:

答案 0 :(得分:1)

在以下行中:

f1 = signal(SIGINT, signal_handler);

f1被分配了一个先前的信号处理程序(在代码中不是signal_handler),该信号可能不是指向您可以用{调用的函数的指针{1}}参数。

要实现此效果,您需要定义第二个信号处理程序并将其分配给上述行之后的int

类似这样的东西:

f1

输出:

#include <signal.h>
#include <stdio.h>

void signal_handler2(int signal)
{
    printf("hahahah2222\n");
}

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1 = signal(SIGINT, signal_handler2);
    f1(3);  //Success
    signal_handler2(3); //OK
    raise(SIGINT);    
}

查看实时 Demo

答案 1 :(得分:1)

signal()至少可以返回3个不是指向实函数的指针的值:

  1. SIG_DFL-通常为((void (*)(int))0)
  2. SIG_IGN-通常为((void (*)(int))1)
  3. SIG_ERR-通常为((void (*)(int))-1)

程序启动时,信号处于SIG_IGNSIG_DFL模式;您可以随后将它们设置为另一个值。

当调用f1 = signal(SIGINT, signal_handler);时,您会返回SIG_DFLSIG_IGN中的一个-而且它们都不是可调用函数的指针(即使它们的类型是指向函数的指针)正确的类型。