0

我正在用 C 创建一个非常简单的程序执行计时器。我将在下面提供示例代码。问题是,当使用+ (即信号)结束程序时,fflush(NULL)它不会刷新所有内容。它们有时仍然出现在消息之后,我想知道为什么。"Hello World\n"stdoutCtrlCSIGINTEstimated running time...

定时器.c

#include <signal.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

#define _TIMER
#include "timer.h"

static clock_t startTime;

int installTimer(void)
{
    errno = 0;
    if (signal(SIGINT, signalHandler) == SIG_ERR ||
        signal(SIGTERM, signalHandler) == SIG_ERR ||
        signal(SIGABRT, signalHandler) == SIG_ERR)
        return 1;
    if (atexit(displayTimer))
        return 1;
    if ((startTime = clock()) == -1)
        return 1;
    return 0;
}

static void displayTimer()
{
    clock_t endTime;
    if ((endTime = clock()) == -1)
        printf("ERROR: clock() failed.\n");
    else
        printf("Estimated running time: %.4fs\n", (endTime - startTime) / (double) CLOCKS_PER_SEC);
}

static void signalHandler(int signal)
{
    fflush(NULL);
    exit(EXIT_FAILURE);
}

计时器.h:

int installTimer(void);

#ifdef _TIMER
   static void displayTimer(void);
   static void signalHandler(int);
#endif

timerTest.c

#include <stdio.h>
#include "timer.h"

int main(void)
{
    if (installTimer())
    {
        printf("ERROR: installTimer() failed.\n");
        return 1;
    }
    int i;
    for (i = 0; i < 300000; ++i)
        printf("Hello World!\n");
    return 0;
}
4

1 回答 1

3

您的程序调用未定义的行为。您不能调用fflush()内部信号处理程序。在信号处理程序中调用 IO 库函数通常是个坏主意。

严格遵守的程序只能从信号处理程序中调用 C 标准库函数abort()、、、_Exit()和。quick_exit()signal()

换句话说,fflush()它不是异步安全的,所以请不要尝试这样做。

有关更多详细信息,请参阅此问题:我需要 glibc 中的异步信号安全函数列表

该问题指向与可能的解决方法的链接。

于 2014-01-11T15:06:32.857 回答