弄清楚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)
一样,我不明白为什么后者可以,但是前者为什么不可以,我认为在这两个调用函数语句之间应该没有“技巧”。
答案 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个不是指向实函数的指针的值:
SIG_DFL
-通常为((void (*)(int))0)
SIG_IGN
-通常为((void (*)(int))1)
SIG_ERR
-通常为((void (*)(int))-1)
程序启动时,信号处于SIG_IGN
或SIG_DFL
模式;您可以随后将它们设置为另一个值。
当调用f1 = signal(SIGINT, signal_handler);
时,您会返回SIG_DFL
和SIG_IGN
中的一个-而且它们都不是可调用函数的指针(即使它们的类型是指向函数的指针)正确的类型。