gpt4 book ai didi

c++ - 信号执行期间的 sigprocmask

转载 作者:搜寻专家 更新时间:2023-10-31 00:19:28 25 4
gpt4 key购买 nike

我目前正在研究使用 sigprocmask 在关键代码段时阻止某些信号(在本例中为 SIGALRMSIGCHLD)正在执行。与这些信号关联的两个信号处理程序都将访问和修改一个中央数据结构,因此在主进程处理它时阻止它们访问它是至关重要的。

目前,我的计划是在代码关键部分的开头简单地禁用这些信号,然后在最后重新启用它们。

void criticalFunction(void) {
// disable signals with sigprocmask
// critical code
// enable signals with sigprocmask
}

但是,将被阻塞的信号的信号处理程序也会调用 criticalFunction。当他们调用 sigprocmask 函数并在他们自己的信号上启用阻塞时会发生什么?他们会拖延还是继续执行? (或者一些第三个条件..)

我能找到的唯一说明如下:

If sigprocmask() is called in a signal handler, returning from the handler may undo the work of sigprocmask() by restoring the original pending signal mask. (http://www.mkssoftware.com/docs/man3/sigprocmask.3.asp)

(这是我之前问题的后续问题:Signal handler accessing queue data structure (race condition?))

最佳答案

请记住,信号处理程序中的默认行为是阻止正在处理的信号。此外,在信号处理程序内部进行函数调用时,您只想调用信号安全函数。也就是说,sigprocmask() 是一个 signal-safe function ,并且如果您使用它来阻止被内部调用的信号处理程序阻止的相同信号,那么实际上什么都不会发生......您将保持与当前相同的信号掩码有。唯一的区别是在信号处理程序内部,只有 SIGALRMSIGCHLD 的信号被保证被阻止(这取决于您所在的信号处理程序),而当您调用 sigprocmask() 来阻止那些特定信号时,这两个信号都将在调用后被阻止。

当您尝试调用 sigprocmask()启用当前在信号掩码中被阻止的信号。这可能会造成一种情况,您最终会在对信号处理程序的调用中出现一定程度的重新进入。换句话说,为你所在的信号处理程序启用信号可能意味着在你退出当前信号处理程序之前,另一个 SIGALRMSIGCHLD 被捕获,你将再次重新进入信号处理程序来处理这个新捕获的信号。只要您在任何关键部分更新后启用信号,那么我认为您应该可以应对这种重入情况,但为了安全起见,您可能只想启用 criticalFunction 中的信号criticalFunction 的最后,而不是在中间的某个地方,当你从 criticalFunction 返回时,不要做任何不异步安全的事情...你必须假设第二个 sigprocmask() 返回后的任何代码可能没有按顺序执行(即,它可能在第二个信号被捕获后执行,并且它的信号-处理程序已运行)。

如果您尝试从 exec 家族调用某些东西,或者您的信号处理程序内部的那种性质的东西,您只需要担心“停滞”。将会发生的是新覆盖的进程将从当前进程继承信号掩码,因此如果当前进程阻塞了某些信号,那么它们也会在新进程中被阻塞。因此,如果新进程假设信号未被阻塞,那么新进程中的信号处理程序将永远不会运行。

顺便说一句,一个警告:不要混合信号和线程!你在你的问题中提到了“主要过程”......我希望这并不意味着你试图混合信号和线程。如果是这样,那就需要一个非常具体的习语,否则你会造成各种困惑。

关于c++ - 信号执行期间的 sigprocmask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8160838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com