使用getch()的循环条件未按预期结束循环

时间:2019-02-08 23:29:14

标签: c++ multithreading loops abort control-flow

我有以下代码,但是即使while为true,也不会结束done循环。它一直在等待_getch()

   while (done || ((c = _getch()) != EOF))
   {
       cout << "Operation aborted" << endl;
       break;
   }
   cout << "Operation finished" << endl;

编辑:实际上,我希望能够中断在另一个线程中执行的长时间操作。我相信我必须在while循环之后加入线程。但是使用以下代码,当我按下一个键时,循环并不会执行。

thread t(Start, folder_path);
while (done || ((c = _getch()) != EOF))
{
    cout << "Operation aborted" << endl;
    exit_signal.set_value();
    break;
}
t1.join();
cout << "Operation finished" << endl;

done为真时,如何结束循环?

1 个答案:

答案 0 :(得分:0)

循环条件的编写方式为:

  • 如果done为true,则逻辑表达式会短路,并且会输入循环主体,而不会评估条件的右侧。
  • 如果done为假,则调用_getch()。如果返回的是char,则表达式为true,并输入循环正文。如果没有可用的字符,_getch()将等到用户键入一个字符为止。仅当遇到文件结尾(即在终端模式下输入Ctrl + Z或从文件重定向cin并到达文件结尾)时,循环才会中断。

如果您想使用非阻塞式键盘输入,则必须首先使用_kbhit(),以检查字符是否可用,然后仅使用_getch()读取字符。对于Linux上的kbhit(),您可以看看here

编辑:您的多线程编辑

首先,如果done是两个线程中都使用的变量(显然是,因为在循环中未更改),请确保它声明了 {{1} } 。如果不是这种情况,则说明您的比赛条件是UB。

现在,您的叙述与代码不符。如果atomic是另一个线程结束的时间,并且您想在此时结束循环,则需要在done上循环。

此外,如果要在另一个线程正在运行时就循环,但要检查键盘并让用户中断代码,则最好在循环中进行检查。顺便说一句,为了避免浪费大量的CPU查询键盘,可以选择在循环主体中sleep_for停留几毫秒。

所以代码最终将以类似

的结构结尾
!done

最后,我不知道std::atomic<bool> done(false); ... thread t(Start, folder_path); while (!done) { if (_kbhit() && ((c = _getch()) != EOF) { // if keystroke available cout << "Operation aborted" << endl; exit_signal.set_value(); // assuming this would make t1 return from folder_path() break; } std::this_thread::sleep_for (std::chrono::milliseconds(500)); // update status bar or do other stuff } t1.join(); cout << "Operation finished" << endl; 在做什么。我希望它所做的事情告诉其他线程停止处理。如果没有,循环将结束,但是无论如何在exit_signal.set_value();上,您必须等待另一个线程完成。