在Ubuntu 12.4上调用警报系统

时间:2013-04-01 02:01:53

标签: c ubuntu signals virtualbox

我个人讨厌这些问题,但我被困住了。我有一个程序,我正在尝试运行 Ubuntu 12.4 (kernal:Linux 3.2.0-39-generic-pae#62-Ubuntu SMP i686 i686 i386 GNU / Linux;编译器:gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3)

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

/*
 * sleep1.c
 *      purpose show how sleep works
 *      usage   sleep1
 *      info    sets handler, sets alarm, pauses, then returns
 */

int main()
{
    void    onbell(int);

    printf("about to sleep for 4 seconds\n");
    signal(SIGALRM, onbell);            /* catch it */
    alarm(4);                   /* set clock    */
    pause();                    /* do nothing   */
    printf("Morning so soon?\n");           /* back to work */
    return 0;
}

void
onbell(int s)
{
    printf("Alarm received from kernel\n");
}

问题是, SIGALRM 永远不会出现。如果我在其上运行 strace ,最后三行是:

rt_sigaction(SIGALRM, {0x80484c1, [ALRM], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
alarm(4)                                = 0
pause(

暂停永不返回。当我在使用 Kernal报告自己的系统上运行相同的代码时:Linux 2.6.24-32-generic i686 GNU / Linux;编译器:gcc(GCC)4.2.4(Ubuntu 4.2.4-1ubuntu4)运行strace的相同代码显示:

rt_sigaction(SIGALRM, {0x8048470, [ALRM], SA_RESTART}, {SIG_DFL}, 8) = 0
alarm(4)                                = 0
pause()                                 = ? ERESTARTNOHAND (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
write(1, "Alarm received from kernel\n", 27Alarm received from kernel
) = 27

知道为什么警报永远不会在 Ubuntu 12.4 系统中被选中,或者可以做些什么来弄清楚发生了什么?

2 个答案:

答案 0 :(得分:1)

您无法安全地从信号处理程序中调用printf()或其他相当多的I / O函数。它有时可行,但不可靠。这不是异步信号安全的。有关其他人的列表,请参阅此页:http://man7.org/linux/man-pages/man7/signal.7.html

然而,它有时会“意外地”工作,让人们认为它通常是可以接受的。

尝试在信号处理程序中增加一个变量,然后检查它在信号处理程序之外的值是否有变化。

答案 1 :(得分:0)

我认为问题在于信号永远不会被触发的可能性。毕竟,strace显示rt_sigaction返回0表示设置信号处置成功。我认为永远不会发送SIGALRM信号。

编辑:看来情况确实如此。我希望@Gonzalo不介意我引用标题为“SIGALRM永远不会触发”的VirtualBox ticket he posted。你说你在虚拟盒子上测试。它似乎反映了这种行为。