使用 getch() 的循环条件未按预期结束循环
Posted
技术标签:
【中文标题】使用 getch() 的循环条件未按预期结束循环【英文标题】:Loop condition using getch() does not end the loop as expected 【发布时间】:2019-02-08 23:29:14 【问题描述】:我有以下代码,但即使done
为真,它也不会结束while
循环。它一直在等待_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
为真时如何结束循环?
【问题讨论】:
while (!done...
?
请提供minimal reproducible example
哪里改了?是多线程代码吗?
done 是布尔值,一旦线程完成,线程将设置为“TRUE”
我希望done
是原子的。
【参考方案1】:
循环条件的写法是:
如果done
为真,则逻辑表达式短路并进入循环体,而不计算条件右侧。
如果done
为假,则调用_getch()
。如果返回一个字符,则表达式为真,并进入循环体。如果没有可用的字符,_getch()
将等到用户键入一个。仅当遇到文件结尾(即在终端模式下输入 Ctrl+Z,或从文件重定向 cin 并到达其结尾)时,循环才会中断。
如果你想要一个非阻塞的键盘输入,你必须先使用_kbhit()
,检查一个字符是否可用,然后只用_getch()
读取字符。对于 linux 上的kbhit()
,你可以看看here。
编辑:您的多线程编辑
首先,如果 done
是一个在两个线程中都使用的变量(显然是这样,因为它没有在循环中更改),请确保它声明了 atomic
。如果不是这种情况,您的竞争条件就是 UB。
现在,您的叙述与代码不符。如果done
是另一个线程完成的时间,并且您想在此时结束循环,则需要在!done
上循环。
此外,如果您想在其他线程运行时循环,但检查键盘并让用户中断代码,您最好在循环中进行检查。顺便说一句,可以选择在循环体中执行几毫秒的sleep_for
,以避免浪费大量 CPU 来查询键盘。
所以代码最终会得到类似
的结构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();
在做什么。我希望它确实可以告诉另一个线程停止处理。如果没有,您的循环将完成,但在join()
处,您无论如何都必须等待另一个线程完成。
【讨论】:
嗨克里斯托夫,谢谢。关于 Linux env 的相同 api 的任何想法? 我相信我必须在while循环之后加入线程。以下是代码。但是当我按键时循环没有被执行。线程 t(开始,文件夹路径); while (done || ((c = _getch()) != EOF)) cout @user1833852 for kbhit on linux,你可以看这里:***.com/a/29335796/3723423 @user1833852 好的,我已经看到您的编辑并相应地更新了我的答案 感谢克里斯托夫的帮助。以上是关于使用 getch() 的循环条件未按预期结束循环的主要内容,如果未能解决你的问题,请参考以下文章