C 检查发送到应用程序的最后一个信号
我希望在发送信号时能够打破while循环。我不确定如何在不使用全局变量或不写入文件的情况下实现这一点。我的最佳选择是使用信号灯吗C 检查发送到应用程序的最后一个信号,c,linux,unix,signals,C,Linux,Unix,Signals,我希望在发送信号时能够打破while循环。我不确定如何在不使用全局变量或不写入文件的情况下实现这一点。我的最佳选择是使用信号灯吗 #include <stdio.h> #include <signal.h> void random() { printf("random!"); } int main(void) { signal(SIGINT, random); // I want this while loop to break if ran
#include <stdio.h>
#include <signal.h>
void random()
{
printf("random!");
}
int main(void) {
signal(SIGINT, random);
// I want this while loop to break if random executes
while (1)
{
pause();
}
// do more stuff after loop
return 0;
}
#包括
#包括
void random()
{
printf(“随机!”);
}
内部主(空){
信号(SIGINT,随机);
//如果随机执行,我希望这个while循环中断
而(1)
{
暂停();
}
//循环后做更多的事情
返回0;
}
循环结束后,您的主函数除了退出外,没有执行任何操作。我理解这可能是简单的问题代码。但是,如果您在想要中断的循环之后实际上没有做任何事情,那么只需将sig处理程序函数更改为:
void random(int sig)
{
printf("random!");
exit(sig); // or exit(0); as in your main()
}
另一方面,如果您需要在
random
(处理程序)和main
之间进行通信,那么为什么不愿意使用变量呢?暂停
块,直到收到调用信号处理程序的信号,这样您就可以添加一个中断代码>在暂停()之后
退出循环。因此,您最好完全摆脱循环
如果您想做的不是等待,而是循环执行某项操作并仅在信号出现时退出,则不能使用pause
。显而易见的方法是使用一个全局变量,但您说您希望避免这种情况。另一种并不简单的方法是使用sigprocmask
/sigpending
代替信号处理程序:
int main()
{
setset_t signals;
sigemptyset(&signals);
sigaddset(&signals, SIGINT);
sigprocmask(SIG_BLOCK, &signals, 0); /* block SIGINT */
while (1) {
/* do stuff */
sigpending(&signals);
if (sigismember(&signals, SIGINT)) {
/* got a SIGINT */
break;
}
}
}
正确的答案实际上取决于你在循环中要做什么。我假设pause()
只是一个伪代码,因为它没有用处
如果您的循环是使用select
或poll
等待的事件循环,那么您可以切换到pselect
(POSIX中的标准)或ppoll
(非标准扩展,但更好,因为select
API非常糟糕),这样也可以让您等待信号。但是,您仍然需要了解如何获得信号发生的通知。仅使用一个信号,您就可以使用EINTR
返回的事实来推断发生了SIGINT
,但如果可能还有其他信号处理程序,这就不太好了。基本上,信号处理基本上是全局的,因此,必须以某种方式涉及全局变量/全局状态。您可以将信号发生的标志存储在全局变量中,并在每次pselect
/ppoll
返回时检查它,或您可以只使用普通标准的poll
并使用,因为您无论如何都需要在信号处理程序中对全局状态执行操作
如果循环不是在等待事件,而是在不断旋转(例如,一个计算循环),则只需阻塞信号(使用sigprocmask
或pthread\u sigmask
)使用sigispending
或sigwaitinfo
定期检查它是一个简单的解决方案,不需要在信号处理程序中使用任何代码。在这种特定情况下,只需删除循环即可。不过,我希望程序在循环后继续执行,谢谢。