信号 - c99 与 gnu99
我有以下代码。当我使用 gnu 扩展(-std=gnu99
)编译它时,程序将在结束之前捕获 5 SIGINT(这是我所期望的)。当没有它的情况下编译时 (-std=c99
) 在第二个之后结束(并且仅输出一行)。
我缺少什么?
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int int_stage = 0;
int got_signal = 0;
void sigint(int parameter)
{
(void)parameter;
got_signal = 1;
int_stage++;
}
int main()
{
signal(SIGINT,sigint);
while(1)
{
if (got_signal)
{
got_signal = 0;
puts("still alive");
if (int_stage >= 5) exit(1);
}
}
return 0;
}
I have the following code. When I compile it with the gnu extensions (-std=gnu99
), the program will catch 5 SIGINT before ending (which I would expect). When compiled without it (-std=c99
) ends after the second (and only outputs one line).
What am I missing?
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int int_stage = 0;
int got_signal = 0;
void sigint(int parameter)
{
(void)parameter;
got_signal = 1;
int_stage++;
}
int main()
{
signal(SIGINT,sigint);
while(1)
{
if (got_signal)
{
got_signal = 0;
puts("still alive");
if (int_stage >= 5) exit(1);
}
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
sigaction(2)
而不是信号(2)
。Linux 手册页的可移植性部分特别介绍了这一点:
使用
std=gnu99
,您将获得 BSD 语义。使用-std=c99
,您将获得 System V 语义。因此,在一种情况下(BSD)信号处理程序被“重新安装”,而在另一种情况下(系统V)信号处理被重置回SIG_DFL。Use
sigaction(2)
rather thansignal(2)
.The Linux man page has this, in particular, in the Portability section:
Using
std=gnu99
, you're getting BSD semantics. Using-std=c99
, you're getting System V semantics. So the signal handler is "reinstalled" in one case (BSD), and the signal disposition is reset back to SIG_DFL in the other (System V).问题是 signal 还会重置信号处理机制,您必须将 sigint 重置为信号处理程序。来自手册
这是如何使用旧的过时的 signal() 调用来做到这一点。
请注意 int_stage 和 got_signal 必须是 sig_atomic_t。
您也可以只调用异步安全函数,请查看 此处查看列表。
请考虑使用 sigaction 或 sigwait。
Sigaction 实际上具有相同的想法,但重新初始化信号处理程序并不是废话。 Sigwait 会停止您的线程,直到收到信号。因此,对于 sigwait,您可以调用任何函数或处理任何数据。如果您愿意,我可以向您展示示例代码。
The problem is that signal also resets the signal handling mechanism, you have to reset sigint as the signal handler. From the manual
This is how to do it with the old antiquated signal() call.
Note how int_stage and got_signal have to be sig_atomic_t.
You can also only call async safe functions, look at here for a list.
Please consider either using sigaction, or sigwait.
Sigaction would have practically the same idea, but no nonsense with re-initializing the signal handler. Sigwait would stop your thread until a signal is received. So, for sigwait, you can call any function or deal with any data. I can show you example code if you desire.
我同意 Ethan Steinberg 的观点 - “忙碌等待”是非常错误的......
但问题是你无法重置信号处理程序。 AFAIK,您必须使用任何版本的 C 来执行此操作(再次调用“signal(SIGINT,sigint)”)。
I agree with Ethan Steinberg - the "busy wait" is So Wrong...
But the problem is that you're failing to reset the signal handler. AFAIK, you must do this (call "signal(SIGINT,sigint)" again) with any version of C.