【问题标题】:C- while loop un-explained behaviourC-while循环无法解释的行为
【发布时间】:2016-03-22 14:22:57
【问题描述】:

我正在尝试运行以下代码:

#include <sys/time.h>
#include <stdio.h>

int main()
{
unsigned int ms, oldms = 0,dif;
struct timeval tv;
while(1)
{
 gettimeofday(&tv, NULL);
 ms=tv.tv_sec; 
 //printf("%d\n",ms-oldms );
 dif=ms-oldms;
 if(dif>3)
   {    
        printf("3 seconds up");
        oldms=ms;
   }
 }
}

我希望它每 3 秒打印一次“3 seconds up”,但它不会显示该消息。 我尝试使用 gdb 对其进行调试,但似乎没有任何问题并且仍然没有输出。 在尝试调试时,我添加了一条 printf 语句,神奇地可以看到输出。

如果我在删除 //printf("%d\n",ms-oldms ); 后运行程序语句,再次没有输出。我不确定发生了什么以及它是否依赖于任何东西。

$gcc --version gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

【问题讨论】:

  • 尝试在你的 printf 上换行
  • @Jorgel ,在 printf 中添加换行符有效。但是,我仍然对这种行为感到困惑。这是我第一次遇到这种情况。
  • 你有无限循环——这是“第一次”。即使没有换行符,如果您在printf 之后添加break,它也可以正常工作。
  • stdoutprintf() 写入的内容)通常会被缓冲,并且在打印换行符(或称为fflush(stdout))之前通常看不到任何内容。

标签: c loops while-loop printf


【解决方案1】:

发布的代码有几个问题

  1. 变量 oldms 在检查经过的时间之前未设置为任何特定值
  2. 如果不调用fflush(stdout); 或格式字符串中的尾随换行符('\n'),则不会输出任何内容(很长一段时间,直到系统标准输出缓冲区被填满)
  3. 为了可读性,公理only one statement per line and (at most) one variable declaration per statement 应用于代码

以下代码编译干净并执行所需的操作

#include <sys/time.h>
#include <stdio.h>

int main()
{
    unsigned int ms;
    unsigned int oldms = 0;
    unsigned int dif;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    oldms = tv.tv_sec;

    while(1)
    {
        gettimeofday(&tv, NULL);
        ms=tv.tv_sec;
        //printf("%d\n",ms-oldms );
        dif=ms-oldms;

        if(dif>3)
        {
            printf("3 seconds up\n");
            oldms=ms;
        }
    }
} // end function: main

【讨论】:

    【解决方案2】:

    输出缓冲是原因。

    stdout 在连接到终端设备时默认为行缓冲。您可以使用fflush(stdout); 或在printf() 中使用\n 将其清除,即printf("3 seconds up\n");。 或使用setbuf(stdout, 0);禁用它

    I/O 通常很慢。因此,实现使用固定大小的缓冲区,一旦它满了就使用 printf。 在实践中,过于频繁地调用fflush(stdout); 会影响性能。

    【讨论】:

    • 所以这个问题出在 printf 上吗?从您的回答来看,我认为代码中发生的 while 循环或大量处理没有任何问题。
    • 是的。循环没有问题。但我不会说这是一个“问题”。 libc 实现进行缓冲有一个很好的理由:性能。
    • 任一 printf("3 seconds up\n");或 printf("\n3 秒后");没用。即使在 printf("3 seconds up\n") 之前添加一个新的 printf("\n") 也无济于事。如果我在代码中放置一个 printf("\n") 而不是注释的 printf (//printf("%d\n",ms-oldms );),则代码可以正常工作
    • @kid “处理量”是因为你的无限循环。在这个循环中没有sleep,得到100%的CPU负载是正常的。
    • @kid \n 仅在您在控制台上打印时有效,而不是在您进行某种重定向时有效。例如,如果你在做./a.out &gt; file,那么就不行。所以在 printf 语句之后调用fflush(stdout);
    猜你喜欢
    • 1970-01-01
    • 2021-12-23
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2015-04-24
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多