因睡眠而导致的奇怪行为()

时间:2011-07-29 08:28:24

标签: c

我刚刚熟悉sleep(),我发现了

#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
    printf("%d",i);
    sleep(1);
}
return 0;

}

这不会打印每次迭代的次数而是在循环时转储所有数字.... 但是当我修改printf ...

#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
    printf("%d\n",i);
    sleep(1);
}
return 0;

}

现在当我添加'\ n'新行时,它按预期工作...为什么它在前者中表现得很奇怪......

6 个答案:

答案 0 :(得分:7)

这是因为输出缓冲区没有被刷新(换句话说,实际上已经提交给终端)。当您编写换行符时,输出缓冲区更可能(但在某些情况下仍然不总是)刷新。许多终端实现都是为了提高性能。要强制执行您想要的行为,您需要在每次fflush(stdout);来电后致电printf,如下所示:

#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
    printf("%d",i);
    fflush(stdout);
    sleep(1);
}
return 0;
}

答案 1 :(得分:3)

您所看到的是行缓冲输出。实际上写入输出是一项昂贵的操作,因此I / O流通常是缓冲。实际上,延迟写入缓冲区直到遇到特定事件。在标准C中,您有三种类型的缓冲:

  • 完全缓冲 - 缓冲区在满时写入。
  • 行缓冲 - 遇到换行符时(您的情况)写入缓冲区。
  • unbuffered - 只要执行I / O功能,就会写入缓冲区。 (适用于错误记录。)

编写缓冲区称为刷新。这就是为什么有一个名为fflush()的stdio函数。您可能还想查看setvbuf()及其参数常量,_IOFBF_IOLBF_IONBF。我相信你可以弄明白他们的意思没有查找它们。 ; - )

修改:此计划按您原先的预期提供:

#include <stdio.h>

// This is the header where sleep() is declared. Don't go without it.
#include <unistd.h>

int main()
{
    int i=0;

    // setvbuf() can be called on a stream only BEFORE
    // you do any I/O on it!
    setvbuf( stdout, NULL, _IONBF, 0 );

    printf( "*********Testing Sleep***********\n" );
    for ( i = 0; i < 10; ++i )
    {
        printf( "%d", i );
        sleep( 1 );
    }
    return 0;
}

答案 2 :(得分:1)

终端的标准输出是行缓冲的,除非有换行符或手动冲洗它,否则不会写入输出。

答案 3 :(得分:0)

这是因为printf()使用缓冲输出以获得更好的性能。打印\n后,缓冲区将刷新到控制台。

答案 4 :(得分:0)

输出被缓冲,因此操作系统有机会优化输出速度。为了确保立即刷新它们,请fflush (stdout);,但通常不会。

答案 5 :(得分:0)

Printf已缓冲。

您可以使用fflush调用强制printf“刷新”其缓冲区。

只需按照您的情况使用\ n将缓冲区推送到stdout。

更详细的讨论是here