Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SIGALRM报警只跳过getchar一次_C - Fatal编程技术网

SIGALRM报警只跳过getchar一次

SIGALRM报警只跳过getchar一次,c,C,我只是使用函数alarm跳过getchar,但有些事情进展不顺利,因为它只跳过一次,我希望它无限期地跳过 例如: #include <signal.h> int duration = 2; main() { cicleProgram(); } void cicleProgram(){ while(opcion != 'q' && opcion != 'Q'){ signal(SIGALRM, (void*)cicleProgram);

我只是使用函数
alarm
跳过
getchar
,但有些事情进展不顺利,因为它只跳过一次,我希望它无限期地跳过

例如:

#include <signal.h>

int duration = 2;

main() {
     cicleProgram();
}

void cicleProgram(){

  while(opcion != 'q' && opcion != 'Q'){

    signal(SIGALRM, (void*)cicleProgram);
    alarm(duration);

    opcion = getchar();
  }
}
#包括
int持续时间=2;
main(){
循环程序();
}
无效循环程序(){
而(opcion!='q'&&opcion!='q'){
信号(SIGALRM,(void*)循环程序);
警报(持续时间);
opcion=getchar();
}
}

我做错了什么?

您正在使用
cicleProgram()
作为信号处理程序(尽管它的类型错误-它应该使用
int
参数)。这意味着您在键入
q
q
之前不会从信号处理程序返回,并且系统可能会在第一个信号处理程序返回之前阻止信号。所以,你永远不会得到第二个信号——它被阻塞了

使用单独的信号处理函数。另请参见并优先使用
sigaction()
,而不是
signal()

并将
intmain(void)
-至少与返回类型一起使用。即使是旧的(C99)版本的标准也需要这样做,更不用说当前的(C11)标准了。我们已经进入21世纪;不要用20世纪的C语言编写代码

有关在信号处理程序中可以执行的操作的信息,请参见


我是否可以在“while”中添加一些控件,以评估信号警报并避免死锁

原始代码存在多个问题,并不是所有可能的问题都被诊断出来。另一个问题是,如果触发了警报,则无法再次设置警报,因此程序将陷入等待状态,直到您键入一个字符

下面是一些您可以使用的实验代码:

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

static int duration = 2;
static volatile sig_atomic_t alarm_fired = 0;

static void alarm_handler(int signum)
{
    //signal(SIGALRM, alarm_handler);
    write(STDOUT_FILENO, "Signalled!\n", 11);
    alarm_fired = signum;
    alarm(duration);
}

static void cicleProgram(void)
{
    int opcion = 0;
    while (opcion != 'q' && opcion != 'Q')
    {
        signal(SIGALRM, alarm_handler);
        alarm(duration);
        if ((opcion = getchar()) == EOF)
            clearerr(stdin);
        if (alarm_fired)
        {
            alarm_fired = 0;
            printf("Alarm!\n");
        }
        printf("c = %d\n", opcion);
    }
}

static void actionProgram(void)
{
    struct sigaction sa = { 0 };
    sa.sa_handler = alarm_handler;
    sa.sa_flags = 0;
    sigfillset(&sa.sa_mask);
    sigaction(SIGALRM, &sa, 0);

    int opcion = 0;
    while (opcion != 'q' && opcion != 'Q')
    {
        alarm(duration);
        if ((opcion = getchar()) == EOF)
            clearerr(stdin);
        if (alarm_fired)
        {
            alarm_fired = 0;
            printf("Alarm!\n");
        }
        printf("c = %d\n", opcion);
    }
}

int main(void)
{
    printf("Using signal (q to quit):\n");
    cicleProgram();
    printf("Using sigaction (q to quit):\n");
    actionProgram();
    return 0;
}

在运行过程中有一些相当长的暂停,但您可以在您的机器上进行试验。您可能需要在
cicleProgram()
alarm\u handler()
函数中重新包含
signal()
,并在
actionProgram()
后定义
opcion
中使用不同的处理程序(不像现在那样使用
signal()
)。您已经将circleProgram设置为SIGALRM的信号处理程序。当发出SIGALRM时,操作系统似乎认为在信号处理程序返回之前,您的程序正在忙于处理该SIGALRM,因此它不会向您发送另一个SIGALRM。您也可能处于死锁状态-您只能使用信号处理程序中的函数。页面向下-有一个POSIX需要异步信号安全的函数列表。在您的实现中,当发送报警信号时,您可能处于
getchar()
等待输入状态,这会导致另一个
circleprogram()
调用在正常程序流之外异步启动。它尝试调用
getchar()
,但原始调用已锁定输入流-死锁。因此,我是否可以在“while”中添加一些控件以评估信号警报并避免死锁?谢谢欢迎来到堆栈溢出。请注意,在这里说“谢谢”的首选方式是投票选出好的问题和有用的答案(一旦你有足够的声誉这么做),并接受对你提出的任何问题最有用的答案(这也会给你的声誉带来一点提升)。请参阅页面,我是否可以在“while”中添加一些控件,以评估信号警报并避免死锁?谢谢谢谢!在我证明你的代码之后,我会更仔细地看看会发生什么,真的,thanksit工作得非常好!我得到了我需要的参考资料,所以它非常有用!谢谢
$ ./al97
Using signal (q to quit):
Signalled!
Signalled!
Signalled!
Signalled!
WonderfulSignalled!

Alarm!
c = 87
c = 111
c = 110
c = 100
c = 101
c = 114
c = 102
c = 117
c = 108
c = 10
Signalled!
Signalled!
q
Alarm!
c = 113
Using sigaction (q to quit):
c = 10
Signalled!
Alarm!
c = -1
Signalled!
Alarm!
c = -1
Signalled!
Alarm!
c = -1
Signalled!
Alarm!
c = -1
ASignalled!
Alarm!
c = -1
lso workingSignalled!
Alarm!
c = -1

c = 65
c = 108
c = 115
c = 111
c = 32
c = 119
c = 111
c = 114
c = 107
c = 105
c = 110
c = 103
c = 10
qSignalled!
Alarm!
c = -1

c = 113
$