C++ std::thread - “在没有活动异常的情况下终止调用”,不想“加入”它
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13999432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
std::thread - "terminate called without an active exception", don't want to 'join' it
提问by DilithiumMatrix
As per This Question, I'm using a thread to terminate a function on user input. My code looks something like:
根据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;
where,
在哪里,
userStop(bool *st) {
char chChar = getchar();
if(chChar == '\n') {
*st = true;
}
}
When I run this, I get the error terminate called without an active exception
. Based on these questions: thread terminate called without an active exception, C++ terminate called without an active exception; it looks like its because I'm not 'join'ing the thread again.
当我运行这个时,我收到错误terminate called without an active exception
。基于这些问题:thread terminate called without an active exception,C++ terminate called without an active exception;它看起来像它,因为我不会再次“加入”线程。
The problem is, I don't want to 'join' the thread -- because then the user will needto provide input for userStop()
to terminate, but I only want the user to provide input if the for-loop is to be broken (which it isn't necessarily).
问题是,我不想“加入”线程——因为那样用户将需要提供输入userStop()
来终止,但我只希望用户在 for 循环被破坏时提供输入(这不一定)。
Thanks!
谢谢!
回答by Sean Cline
The trouble you are encountering is a result of the stopThread
going out of scope on the stack. The C++ standard has the following to say about this:
您遇到的问题是stopThread
超出堆栈范围的结果。C++ 标准对此有以下说明:
30.3.1.3thread destructor [thread.thread.destr]
~thread();
If joinable()then terminate(), otherwise no effects. [ Note:Either implicitly detaching or joining a joinable()thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. — end note]
30.3.1.3线程析构函数[thread.thread.destr]
〜线程();
如果joinable()然后终止(),否则没有效果。[注意:在其析构函数中隐式分离或加入joinable()线程可能会导致难以调试正确性(对于分离)或性能(对于连接)错误,只有在引发异常时才会遇到。因此,程序员必须确保在线程仍可连接时永远不会执行析构函数。—尾注]
What this means is that you should not let threads go out of scope without first calling either join()
or detach()
.
这意味着您不应该在没有首先调用join()
或 的情况下让线程超出范围detach()
。
The way you describe it, you want the thread to go out of scope without joining so it will continue to run as your application runs. That requires a call to detach()
. From there, I can only offer a little wisdom...
按照您的描述方式,您希望线程在不加入的情况下超出范围,以便在您的应用程序运行时继续运行。这需要调用detach()
. 从那里,我只能提供一点智慧......
That thread is now completely responsible for its own lifetime. If it doesn't return on its own, it will run forever (until the process terminates).
You are getting user input, presumably from something like
cin
orgetch()
. If these are accessed from multiple threads, you do not have much assurance that there are not race conditions in their library implementations. Tread lightly.
该线程现在完全负责它自己的生命周期。如果它不自行返回,它将永远运行(直到进程终止)。
您正在获取用户输入,大概来自类似
cin
或getch()
。如果这些是从多个线程访问的,您就无法保证它们的库实现中没有竞争条件。轻踩。
回答by Yakk - Adam Nevraumont
In your standard input thread, you'll want to asynchronously read from input. And wake up on both a demand to stop reading, and new input.
在您的标准输入线程中,您需要异步读取输入。并在要求停止阅读和新输入时醒来。
Terminating a thread without joining is not a reasonable thing to do. So what you need to be able to do is say "yo thread, finish up right now", then be able to expect that the join will finish promptly. This can even be via a two-step handshake ("yo thread, finish up", followed by "ok ok, I managed to clean up, join me now") in some cases.
在不加入的情况下终止线程是不合理的。因此,您需要能够做的是说“哟线程,立即完成”,然后能够期望加入将迅速完成。在某些情况下,这甚至可以通过两步握手(“哟线程,完成”,然后是“好吧,我设法清理,现在加入我”)。
Note that your loop to 1000
looks really ridiculous: user input timeouts should generally be based on actual time passing, or some other event occurring that makes the user input non-useful.
请注意,您的循环 to1000
看起来真的很荒谬:用户输入超时通常应基于实际经过的时间,或发生的其他一些使用户输入无用的事件。
回答by MikeB
Terminating a thread is a bad idea -- you should make your thread exit gracefully. If you did terminate the thread, you'd end up causing code in the getch()
function to end unexpectedly. What if that code was in the middle of managing a data structure, allocating or freeing memory, or doing some other work that had to execute until completion? You'd end up leaving something in an invalid state, and you'd eventually crash when that invalid state was exercised.
终止一个线程是一个坏主意——你应该让你的线程优雅地退出。如果你确实终止了线程,你最终会导致getch()
函数中的代码意外结束。如果该代码正在管理数据结构、分配或释放内存或执行其他一些必须执行直到完成的工作怎么办?您最终会将某些东西置于无效状态,并且在执行该无效状态时您最终会崩溃。