C:SIGALRM - 每秒显示消息的警报

viv*_*vav 8 c alarm

所以我试着每秒钟拨打一个警报来显示"仍在工作......"的消息.我包括了signal.h.

在我的主要之外,我有我的功能:(我从来没有为int声明/定义s)

void display_message(int s);   //Function for alarm set up
void display_message(int s) {
     printf("copyit: Still working...\n" );
     alarm(1);    //for every second
     signal(SIGALRM, display_message);
}
Run Code Online (Sandbox Code Playgroud)

然后,在我的主要

while(1)
{
    signal(SIGALRM, display_message);
    alarm(1);     //Alarm signal every second.
Run Code Online (Sandbox Code Playgroud)

一旦循环开始,那就在那里.但该程序从未输出"仍在工作......"的消息.我做错了什么?谢谢,非常感谢.

Pot*_*ter 15

信号处理程序不应包含"业务逻辑"或进行库调用printf.见C11§7.1.4/ 4及其脚注:

因此,信号处理程序通常不能调用标准库函数.

所有信号处理程序应该设置一个标志,由非中断代码作用.即使添加了一些I/O其他功能,该程序也能正常运行并且不会有崩溃的风险:

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

volatile sig_atomic_t print_flag = false;

void handle_alarm( int sig ) {
    print_flag = true;
}

int main() {
    signal( SIGALRM, handle_alarm ); // Install handler first,
    alarm( 1 ); // before scheduling it to be called.

    for (;;) {
        if ( print_flag ) {
            printf( "Hello\n" );
            print_flag = false;
            alarm( 1 );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但请注意,旋转循环是一种糟糕的编程方式.此示例使用100%CPU功率,因为​​它从不睡觉.此外alarm似乎没有C标准定义,虽然POSIX标记它,我记得它是K&R的一部分.因此,就可移植性而言,您可以使用另一个POSIX工具.


oog*_*oga 5

移动呼叫signalalarm只是你的循环之前。alarm高速反复呼叫,不断将闹钟重置为从那一刻起的一秒内,因此您永远不会到达那一秒的尽头!

例如:

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

void display_message(int s) {
     printf("copyit: Still working...\n" );
     alarm(1);    //for every second
     signal(SIGALRM, display_message);
}

int main(void) {
    signal(SIGALRM, display_message);
    alarm(1);
    int n = 0;
    while (1) {
        ++n;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)