根据This Question,我正在使用一个线程终止用户输入的函数。我的代码看起来像:
bool stopper = false;
thread stopThread(userStop, &stopper); // start thread looking for user input
for(int i = 0; i < 1000; i++) {
if(stopper) { break; } // break if desired
// Do stuff
}
return 0;
其中,
userStop(bool *st) {
char chChar = getchar();
if(chChar == '\n') {
*st = true;
}
}
当我运行此操作时,我收到错误terminate called without an active exception
。基于以下问题:thread terminate called without an active exception,C++ terminate called without an active exception;它看起来像是因为我不再“加入”线程了。
问题是,我不想'加入'该主题 - 因为用户将 需要 为userStop()
提供输入终止,但我只希望用户在断开for循环时提供输入(不一定是这样)。
谢谢!
答案 0 :(得分:34)
您遇到的麻烦是stopThread
超出堆栈范围的结果。 C ++标准有以下几点说明:
30.3.1.3 thread析构函数[thread.thread.destr]
〜螺纹();
如果 joinable()则终止(),否则无效果。 [注意:要么 在析构函数中隐式分离或连接 joinable()线程 可能导致难以调试正确性(用于分离)或 性能(用于连接)仅在异常时遇到错误 提高。因此,程序员必须确保析构函数永远不会 在线程仍可加入时执行。 - 结束记录]
这意味着如果没有先调用join()
或detach()
,就不应让线程超出范围。
您描述它的方式,您希望线程超出范围而不加入,因此它将在您的应用程序运行时继续运行。这需要拨打detach()
。从那里,我只能提供一点点智慧......
该线程现在对其自身的生命负全部责任。如果它不会自行返回,它将永远运行(直到进程终止)。
您正在接收用户输入,可能来自cin
或getch()
。如果从多个线程访问它们,则无法确保其库实现中没有竞争条件。 轻轻踩踏。
答案 1 :(得分:4)
在标准输入线程中,您需要从输入异步读取。并且唤醒了停止阅读和新输入的要求。
在没有加入的情况下终止线程是不合理的事情。所以你需要做的就是说“哟线程,现在完成”,然后能够期望加入将立即完成。在某些情况下,甚至可以通过两步握手(“哟线程,完成”,然后“确定,我设法清理,现在加入我”)。
请注意,您对1000
的循环看起来非常荒谬:用户输入超时通常应基于实际传递的时间,或者其他一些使用户输入无用的事件。
答案 2 :(得分:1)
终止一个线程是一个坏主意 - 你应该让你的线程优雅地退出。如果您确实终止了该线程,那么您最终会导致getch()
函数中的代码意外终止。如果该代码正在管理数据结构,分配或释放内存,或者做一些必须执行直到完成的其他工作,该怎么办?你最终会把某些东西留在无效的状态,并且当这个无效状态被执行时你最终会崩溃。