我已阻止,然后通过以下代码等待信号:
sigset_t set;
sigfillset(&set); // all signals
sigprocmask(SIG_SETMASK, &set, NULL); // block all signals
siginfo_t info;
int signum = sigwaitinfo(&set, &info); // wait for next signal
struct sigaction act;
sigaction(signum, NULL, &act); // get the current handler for the signal
act.sa_handler(signum); // invoke it
由于处理程序设置为SIG_DFL
(定义为0
),最后一行生成分段错误。如果将默认处理程序设置为SIG_DFL
或,该如何手动调用它SIG_IGN
?另请注意,该SIG_IGN
定义为1
。
当你发现你不能调用SIG_DFL和SIG_IGN 本身 。但是,您可以或多或少模仿它们的行为。
简而言之,模仿正常信号处理将是:
sa_handler
s 很容易这是您想要的吗?
#include <signal.h>
#include <stdlib.h>
/* Manually dispose of a signal, mimicking the behavior of current
* signal dispositions as best we can. We won't cause EINTR, for
* instance.
*
* FIXME: save and restore errno around the SIG_DFL logic and
* SIG_IGN/CHLD logic.
*/
void dispatch_signal(const int signo) {
int stop = 0;
sigset_t oset;
struct sigaction curact;
sigaction(signo, NULL, &curact);
/* SIG_IGN => noop or soak up child term/stop signals (for CHLD) */
if (SIG_IGN == curact.sa_handler) {
if (SIGCHLD == signo) {
int status;
while (waitpid(-1, &status, WNOHANG|WUNTRACED) > 0) {;}
}
return;
}
/* user defined => invoke it */
if (SIG_DFL != curact.sa_handler) {
curact.sa_handler(signo);
return;
}
/* SIG_DFL => let kernel handle it (mostly).
*
* We handle noop signals ourselves -- "Ign" and "Cont", which we
* can never intercept while stopped.
*/
if (SIGURG == signo || SIGWINCH == signo || SIGCONT == signo) return;
/* Unblock CONT if this is a "Stop" signal, so that we may later be
* woken up.
*/
stop = (SIGTSTP == signo || SIGTTIN == signo || SIGTTOU == signo);
if (stop) {
sigset_t sig_cont;
sigemptyset(&sig_cont);
sigaddset(&sig_cont, SIGCONT);
sigprocmask(SIG_UNBLOCK, &sig_cont, &oset);
}
/* Re-raise, letting the kernel do the work:
* - Set exit codes and corefiles for "Term" and "Core"
* - Halt us and signal WUNTRACED'ing parents for "Stop"
* - Do the right thing if we forgot to handle any special
* signals or signals yet to be introduced
*/
kill(getpid(), signo);
/* Re-block CONT, if needed */
if (stop) sigprocmask(SIG_SETMASK, &oset, NULL);
}
更新 (针对OP的精彩问题)
1:此插槽是否在sigwaitinfo之后?
是。就像是:
... block signals ...
signo = sigwaitinfo(&set, &info);
dispatch_signal(signo);
2:为什么不引发那些由SIG_IGN处理的信号,无论如何它们都会被忽略
与三个系统调用(重新引发,取消屏蔽,重新屏蔽)相比,在用户空间中进行noop效率更高。此外,当SIG_IGNored时,CHLD具有特殊的语义。
3:为什么要特别对待SIGCHLD?
最初(检查答案是否编辑)我没有-在SIG_IGN情况下重新提出,因为IGNored
CHLD信号告诉内核自动获得子级
。
但是,我进行了更改,因为“自然的”
CHLD信号携带有关终止过程的信息
(至少PID,状态和实际UID)。用户生成的CHLD信号不具有相同的语义,在我的测试中,对它们进行IGNoring不会导致2.6自动收起SIGCHLD被“遗漏”的排队的僵尸。所以,我自己做。
4:为什么与“停止”相关的信号会阻止CONT。 不会为CONT调用默认的处理程序吗?
如果我们停止(不执行)并且CONT被阻止,我们将永远不会收到唤醒我们的信号!
5:为什么不叫加注而不是加注的底线?
个人喜好; raise()
也可以。
问题内容: 我试图了解Linux如何处理进程调度和线程调度。我读过Linux可以安排进程和线程。 Linux是否具有线程调度程序和进程调度程序?如果是,他们如何合作? 问题答案: 的Linux内核调度器被实际调度的任务,并且这些要么螺纹或(单线程)工艺。 因此,在调度程序的上下文中, 任务 (内核内部)是正在调度的事物,可以是某些 内核线程( 例如或),多线程进程的某些 用户线程 (例如)或单线程
我有一个UITableView,在委托(视图控制器)中,我已经实现了该函数 然后,我测试编辑样式 作为删除的一部分,我请求用户确认,如果他们选择“是”,与该行相关的项目将被删除,如果他们选择“否”,我将重置编辑样式。 我似乎遇到的问题是没有调用任何完成处理程序。我在其他地方使用过这种格式,没有任何问题。 该警报将显示标题、消息以及按钮“取消”和“是”。如果我点击其中任何一个,什么都不会发生。警报被
我试图使用一个简单的服务器-客户端应用程序(代码见下文)进入Netty。 我在与两个问题作斗争: null KJ 这就是服务器的创建方式: 其中一个处理程序类(FeedbackServerHandler执行完全相同的操作,但解析为整数):
快速免责声明:我是一个。Net开发人员,可能没有提供您需要的有关环境的所有信息,但可以根据要求获取信息。我们有COBOL程序员,但他们从来没有这样做过。 我们正在将带有DB2数据库的大型机应用程序转换为。Net MVC应用程序和SQL数据库。我们希望从DB2上的COBOL存储过程调用一个大型机COBOL批处理程序。我读过这篇文章,但是我还没有找到一个好的例子来说明如何创建一个调用COBOL程序的C
问题内容: 我正在学习React,并按照本教程创建了一个简单的Tic- Tac-Toe游戏,您可以在CodePen中查看。 对于在Board组件的函数内部返回的Square组件的属性中的箭头功能如何工作,我感到困惑。同样,我拥有的游戏组件也同样如此。我以为我可以不用箭头功能(就像一样)来编写它,但这会中断游戏。 问题答案: 期望功能。箭头函数没有自己的功能; 使用封闭执行上下文的值。箭头功能可替代
我正在开发一个用PHP编写的预分叉TCP套接字服务器。 守护进程(父进程)分叉一定数量的子进程,然后等待,直到它被告知退出并且子进程都走了或者它收到信号。 SIGINT和SIGTERM使其将SIGTERM发送给所有子级。 孩子们建立了他们自己的信号处理器:SIGTERM导致一个干净的退出。SIGUSR1导致它转储一些状态信息(只需在下面的示例代码中打印出它收到了信号)。 如果子异常退出,则父级启动