简单信号 - C编程和报警功能

qwe*_*wer 25 c signals

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


void  ALARMhandler(int sig)
{
  signal(SIGALRM, SIG_IGN);          /* ignore this signal       */
  printf("Hello");
  signal(SIGALRM, ALARMhandler);     /* reinstall the handler    */
}

int main(int argc, char *argv[])
{
  alarm(2);                     /* set alarm clock          */
  while (1)
    ;
  printf("All done");
}
Run Code Online (Sandbox Code Playgroud)

我希望程序在2秒后打印"你好",而输出是"zsh:alarm ./a.out"

知道发生了什么事吗?

And*_*mar 33

您忘记最初设置警报处理程序.改变main()喜欢的开始:

int main(int argc, char *argv[])
{
   signal(SIGALRM, ALARMhandler);
   ...
Run Code Online (Sandbox Code Playgroud)

此外,信号处理程序可能不会打印任何内容.那是因为C库缓存输出直到它看到行结束.所以:

void  ALARMhandler(int sig)
{
  signal(SIGALRM, SIG_IGN);          /* ignore this signal       */
  printf("Hello\n");
  signal(SIGALRM, ALARMhandler);     /* reinstall the handler    */
}
Run Code Online (Sandbox Code Playgroud)

对于真实世界的程序,从信号处理程序打印不是很安全.信号处理程序应该尽可能少,最好只在这里或那里设置一个标志.并且应该宣布旗帜volatile.

  • 真实世界的例子:我曾经在一个使用Access数据库作为后端的系统上工作,在某些情况下,信号处理程序中的`printf()`调用将写入.mdb文件而不是stdout,从而使用数据库无法修复. (23认同)

McP*_*inM 9

您没有在函数中设置处理程序main.

在你做之前alarm(2),把signal(SIGALRM, ALARMhandler);你的main.

它应该工作.

请注意,永远不会打印"All Done",因为在信号处理器运行后您将保持while(1)循环.如果你想要打破循环,你需要有一个信号处理程序改变的标志.

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

/* number of times the handle will run: */
volatile int breakflag = 3;

void handle(int sig) {
    printf("Hello\n");
    --breakflag;
    alarm(1);
}

int main() {
    signal(SIGALRM, handle);
    alarm(1);
    while(breakflag) { sleep(1); }
    printf("done\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • +1对于好的程序.我认为你必须在信号处理程序中调用`alarm(2)`:通常一个`alarm()`调用只生成一个`SIGALRM` (4认同)

Ark*_*nez 5

您不是先安装信号处理程序.
在实际接收信号之前,您需要告诉系统您想要处理信号,因此您需要signal()在信号到来之前从main 调用.

int main(int argc, char *argv[])
{
  signal(SIGALRM, ALARMhandler);     /* install the handler    */
  alarm(2);                     /* set alarm clock          */
  while (1);
}
Run Code Online (Sandbox Code Playgroud)