如何从C语言中的信号处理程序获取返回值?
我在link中读到了一个类似的问题,但它并没有解决我的问题,所以我为重复的问题道歉 我有下面的代码,在程序执行时基本上接收Ctrl+C和Ctrl+Z,但我希望2个信号处理函数在从终端接收信号时返回1 该链接提到了一些关于使用typedef的内容,并且对于C来说是相当新的,我不知道如何在我的代码中实现这一点 代码如下:如何从C语言中的信号处理程序获取返回值?,c,signals,C,Signals,我在link中读到了一个类似的问题,但它并没有解决我的问题,所以我为重复的问题道歉 我有下面的代码,在程序执行时基本上接收Ctrl+C和Ctrl+Z,但我希望2个信号处理函数在从终端接收信号时返回1 该链接提到了一些关于使用typedef的内容,并且对于C来说是相当新的,我不知道如何在我的代码中实现这一点 代码如下: #include <stdio.h> #include <signal.h> /* Signal Handler for SIGINT */ void s
#include <stdio.h>
#include <signal.h>
/* Signal Handler for SIGINT */
void sigintHandler(int sig_num) {
signal(SIGINT, sigintHandler);
printf("\n Cannot be terminated using Ctrl+C \n");
fflush(stdout);
}
/* Signal Handler for SIGTSTP */
void sigtstpHandler(int sig_num) {
signal(SIGTSTP, sigtstpHandler);
printf("\tCtrl+z received\n");
fflush(stdout);
}
int main (void) {
signal(SIGINT, sigintHandler);
signal(SIGTSTP, sigtstpHandler);
while(1) {} //infinite loop.
return 0;
}
返回1而不是仅返回void。这样我就可以做
int sigIntReturn = signal(SIGINT, sigintHandler);
在主要功能中 信号处理程序就像一个中断,不会返回给任何人。您发布的链接在设置信号处理程序时讨论返回值,而不是信号处理程序返回值(请注意,
signal
只是设置信号处理程序)
但是,您可以执行类似于以下的操作,以便在信号发生时从main返回
volatile int g_flag = 0;
void sigintHandler(int sig_num) {
signal(SIGINT, sigintHandler);
/* Not safe to use these functions in a signal handler */
printf("\n Cannot be terminated using Ctrl+C \n");
fflush(stdout);
g_flag = 1;
}
int main (void) {
signal(SIGINT, sigintHandler);
signal(SIGTSTP, sigtstpHandler);
while(g_flag == 0) {} //infinite loop.
return g_flag;
}
请注意,这是一个繁忙的循环,主要是不推荐。你可以用eventfd之类的东西来发信号。我不明白这个问题。返回1到什么?@DavidSchwartz抱歉。我在问题中添加了一个编辑。请阅读。标准指令
void
。不能返回值。改用(volatile
)全局变量(有点像errno
)。无法从信号处理程序返回值,因为没有调用程序接收它。唯一可能帮助您的是wait()
函数之一。另外:SIGSTOP(和SIGKILL)无法捕获)信号
甚至不发送信号-它只是设置信号处理kill
发送信号。这不起作用。编译器以外的组件可以自由地优化,而循环不检查g_标志
(即使它是易失性的
)。您需要使用sig_atomic_t
或等效工具——请参阅C标准。@user100000-信号处理程序可用的唯一通信机制是通过全局变量。如果你不能使用它们,不要做信号处理。很简单,注意许多函数不是同步信号安全的。特别是,标准I/o函数不是。这是C标准所说的。我想不出任何可能失败的方法,但你永远不知道未来的硬件可能会做什么。@user1969104这意味着处理器的性能没有达到你的预期。但是,在C标准中,什么赋予了您期望的权利?您有权期望C编译器生成代码,使CPU以一种结果符合C标准要求的方式执行,仅此而已。C99表示“如果信号不是由于调用abort
或raise
函数而发生的,则如果信号处理程序引用任何具有静态存储持续时间的对象,而不是通过向声明为volatile sig_atomic_t
[]的对象赋值,则该行为是未定义的。”@user1969104 C99的sig_atomic_t
类型保证在信号处理程序的上下文中是原子的(即没有“一半”更新)。这意味着它可以是实现中的任何类型,只要其属性得到保证。例如,在我的64位Linux上,sig_atomic_t
的类型定义为int
。但在不同的体系结构上,它可能被类型定义为其他类型——这是一个实现的选择,只要它们选择的类型能够保证sig\u atomic\t
所需的语义。无论int
工作与否,当sig\u atomic\u t
可用时,都没有理由使用int
。
volatile int g_flag = 0;
void sigintHandler(int sig_num) {
signal(SIGINT, sigintHandler);
/* Not safe to use these functions in a signal handler */
printf("\n Cannot be terminated using Ctrl+C \n");
fflush(stdout);
g_flag = 1;
}
int main (void) {
signal(SIGINT, sigintHandler);
signal(SIGTSTP, sigtstpHandler);
while(g_flag == 0) {} //infinite loop.
return g_flag;
}