c++意外挂起时间

C++ unexpected hangtime

本文关键字:挂起时间 意外 c++      更新时间:2023-10-16

我正试图在我的程序中编写一个函数,该函数加载216,555个单词的巨大文本文件,并将它们作为字符串放入集合中。这可以正常工作,但正如预期的那样,在循环遍历文件时,它会挂起几微秒。但是我的循环有一些奇怪的地方,它的行为不正常。请花点时间阅读,我相信这是有正当理由的,但我不知道该搜索什么。

下面的代码是这样的:
ifstream dictionary;
dictionary.open("Dictionary.txt");
if(dictionary.fail())
{
    cout<<"Could not find Dictionary.txt. Exiting."<<endl;
    exit(0);
}
int i = 0;
int progress = 216555/50;
cout<<"Loading dictionary..."<<endl;
cout<<"<                                                  >"<<endl;
cout<<"<";
for(string line; getline(dictionary, line);)
{
    usleep(1); //Explanation below (not the hangtime)
    i++;
    if(i%progress == 0)
        cout<<"=";
    words.insert(line);
}

for循环从文件中获取每个字符串,并将它们插入到映射中。这是一个控制台应用程序,我希望用户看到进度。虽然没耽搁多少时间,但我还是想这么做。如果你看不懂代码,我会试着解释。

程序启动时,首先打印"Loading Dictionary…",然后是一个以50个空格分隔的"<"和一个">"。然后在下一行:"<"后面跟着"=",它循环遍历每433个单词(216555/50)。这样做的目的是让用户可以看到进度。在循环的中途想要的输出是这样的:

Loading dictionary...
<                                                  >
<=========================                         

我的问题是:显示了正确的输出,但不是在预期的时间。它打印出完整的进度条,但只有在它挂起并完成循环之后。这怎么可能呢?显示了正确的'='数目,但在挂起几微秒后,它们都同时弹出。我添加了ussleep(1)使挂起时间更长一点,但同样的事情发生了。if语句显然有效,否则'='根本不会显示,但感觉我的程序在整个循环之后堆叠了计数调用。

最奇怪的是,在for循环开始之前的最后一个cout<<"<";,也与该行的其余部分同时显示;循环结束后。为什么?怎么做?

您从不刷新流,因此输出只是进入缓冲区。

cout<<"=";改为cout<<"="<<std::flush;

需要刷新输出流。

cout << "=" << std::flush;

程序正在 "堆叠计数调用"。它被称为输出缓冲,每个主要的操作系统都有这个功能。

当处于交互模式时(正如您的程序打算使用的那样),输出按行缓冲;也就是说,当看到换行符时,它将被强制到终端。你也可以设置块缓冲(强制输出之间的固定字节数);用于管道输出)和未缓冲。

c++提供了std::flush流修饰符来强制在任何点输出。它可以这样使用:

cout << "=" << std::flush;

这会使你的程序变慢一点;缓冲的目的是为了提高效率。但是,由于您只会执行大约51次,因此速度的减慢应该可以忽略不计。