gpt4 book ai didi

c - 如何连续交替信号处理程序

转载 作者:太空宇宙 更新时间:2023-11-04 10:31:57 25 4
gpt4 key购买 nike

我想用 c 语言为 linux 编写一个程序,它捕获第一个 SIGUSR1 信号,忽略第二个信号并继续这种行为(捕获-忽略)连续的 SIGUSR1 信号。

我想知道如何在两个处理程序之间保持交替,因为一旦我将处理程序设置为 SIG_IGN,信号将被忽略,我将无法检测到它并采取相应的行动。

这是我试过的代码:

int tst;
void sigusr1_handler(){
if(tst==0){
signal(SIGUSR1,SIG_IGN);
tst=1;
}
else tst= 0;
}


int main(){
signal(SIGUSR1, sigusr1_handler);
tst=1;
while(1){}
return 0;
}

最佳答案

你没有。

您可以做的是让您的信号处理程序决定是否做某事——例如,是否调用另一个函数。然而,这并不完全可靠,因为 standard POSIX signalsSIGUSR1 没有排队。如果在(几乎)同时发送两个或多个信号,则实际上只有一个信号被传送。 POSIX 实时信号(SIGRTMIN+0SIGRTMAX-0——从程序员的角度来看,只有数量和语义不同)被排队,但即使它们也可以被丢弃在某些情况下。

在所有情况下,请记住信号处理函数只能使用 async-signal safe functions .如果您需要能够使用所有功能,您应该改为阻塞所有线程中的信号,并让专用线程使用例如接收信号sigwaitinfo() .在这种情况下,您没有信号处理函数,而是一个接收信号的专用线程,因此可以自由使用它想要的任何函数。

如果我们将问题改写为“如何在单线程程序中交替处理传递的信号?”,答案很简单:您使用volatile sig_atomic_t 计数器。

为了在两个选择之间交替,do_something_odd() 首先:

#include <signal.h>

void my_signal_handler(int signum)
{
static volatile sig_atomic_t count = 0;

switch (++count) {

case 1:
do_something_odd();
break;

default:
count = 0;
do_something_even();
break;
}
}

为了在三种情况之间交替,您可以根据需要添加更多的 case 语句:

#include <signal.h>

void my_signal_handler(int signum)
{
static volatile sig_atomic_t count = 0;

switch (++count) {

case 2:
do_something_2_of_3();
break;

case 1:
do_something_1_of_3();
break;

default:
count = 0;
do_something_3_of_3()
break;
}
}

以上假定您使用 sigaction() 安装信号处理程序.sa_flags 中没有 SA_SIGINFO

POSIX 标准规定您最多可以处理 128 种情况(因为 sig_atomic_t 保证能够表示值 0127,包括)这样。

您可以使用 unsigned intunsigned long 做更大的集合,但是您不能在 中有 SA_NODEFER。 sa_flags,如果同一处理程序用于多个信号,则 .sa_mask 必须让所有其他信号由同一处理程序集处理。这确保信号处理程序不会被传递给同一处理程序的另一个信号中断,并允许我们使用非原子计数器变量。

在多线程程序中,必须依赖编译器提供的原子操作,无论是遗留的 __sync内置,或 __atomic内置插件。它们不是 GCC 特定的;至少 Intel Compiler Collection 和 clang 也提供了它们。为了在两个选项之间交替,our = __atomic_xor_fetch(&counter, 1, __ATOMIC_SEQ_CST);our = __sync_xor_and_fetch(&counter, 1); 可用于获取和翻转计数器原子地介于 0 和 1 之间。对于非二次幂的选项,通常使用比较和交换循环。

关于c - 如何连续交替信号处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39427204/

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