[英]std::thread thread spun off in object, when does it terminate?
If I spin off an std::thread
in the constructor of Bar
when does it stop running? 如果我在
Bar
的构造函数中关闭std::thread
,它什么时候停止运行? Is it guaranteed to stop when the Bar
instance gets destructed? 当
Bar
实例被破坏时,它是否可以保证停止?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
...
void foo() {
while (true) {//do stuff//}
}
private:
std::thread thread;
};
EDIT: How do I correctly terminate the std::thread
in the destructor? 编辑:如何正确终止析构函数中的
std::thread
?
If I spin off an std::thread in the constructor of Bar when does it stop running?
如果我在Bar的构造函数中关闭std :: thread,它什么时候停止运行?
the thread will run as long as it executing the callable you provided it, or the program terminates. 只要它执行你提供的调用,或者程序终止,线程就会运行。
Is it guaranteed to stop when the Bar instance gets destructed?
当Bar实例被破坏时,它是否可以保证停止?
No. In order to guarantee that, call std::thread::join
in Bar
destructor. 不。为了保证这一点,在
Bar
析构函数中调用std::thread::join
。
Actually, if you hadn't call thread::join
or thread::detach
prior to Bar::~Bar
, than your application will be terminated by calling automatically to std::terminate
. 实际上,如果你没有在
Bar::~Bar
之前调用thread::join
或thread::detach
,那么你的应用程序将通过自动调用std::terminate
来std::terminate
。 so you must call either join
(preferable) or detach
(less recommended). 所以你必须要么
join
(优先)或detach
(少推荐)。
you also want to call therad::join
on the object destructor because the spawned thread relies on the object to be alive , if the object is destructed while your thread is working on that object - you are using destructed object and you will have undefined behavior in your code. 你还想在对象析构函数上调用
therad::join
,因为生成的线程依赖于对象是活的 ,如果在你的线程处理该对象时对象被破坏 - 你正在使用被破坏的对象而你将有未定义的行为在你的代码中。
Short answer: Yes and no. 简短的回答:是的,不是。 Yes, the thread ends, but not by the usual way (killing the thread), but by the main thread exiting due to a
std::terminate
call. 是的,线程结束,但不是通常的方式(杀死线程),而是由于
std::terminate
调用退出的主线程。
Long answer: The thread can only be safely destructed when the underlying function ( thread ) has finished executing. 答案很长:只有在底层函数( 线程 )执行完毕后才能安全地破坏线程 。 This can be done in 2 ways
这可以通过两种方式完成
join()
, which waits for the thread to finish (in your case, never) join()
,等待线程完成(在你的情况下,永远不会) detach()
, which detaches the thread from the main thread (in this case, the thread will end when the main thread closes - when the program terminates). detach()
,它将线程与主线程分离(在这种情况下,线程将在主线程关闭时结束 - 当程序终止时)。 If the destructor is called if all of those conditions don't apply, then std::terminate
is called: 如果在所有这些条件都不适用的情况下调用析构函数,则调用
std::terminate
:
it was default-constructed
它是默认构造的
it was moved from
它被移走了
join()
has been called已调用
join()
detach()
has been called已经调用了
detach()
The C++ threading facilities do not include a built-in mechanism for terminating a thread. C ++线程工具不包含用于终止线程的内置机制。 Instead, you must decide for yourself: a) a mechanism to signal the thread that it should terminate, b) that you do not care about the thread being aborted mid-operation when the process terminates and the OS simply ceases to run it's threads any more.
相反,你必须自己决定:a)一个机制来通知线程它应该终止,b)你不关心线程在进程终止时在操作中被中止并且操作系统只是停止运行它的线程任何更多。
The std::thread
object is not the thread itself but an opaque object containing a descriptor/handle for the thread, so in theory it could be destroyed without affecting the thread, and there were arguments for and against automatic termination of the thread itself. std::thread
对象不是线程本身,而是包含线程的描述符/句柄的不透明对象,因此理论上它可以在不影响线程的情况下被销毁,并且存在支持和反对线程自动终止的参数。 Instead, as a compromise, it was made so that destroying a std::thread
object while the thread remained running and attached would cause the application to terminate. 相反,作为妥协,它是这样做的,以便在线程保持运行和附加时销毁
std::thread
对象将导致应用程序终止。
As a result, In it's destructor there is some code like this: 结果,在它的析构函数中有一些代码如下:
~thread() {
if (this->joinable())
std::terminate(...);
}
Here's an example of using a simple atomic variable and checking for it in the thread. 这是一个使用简单原子变量并在线程中检查它的示例。 For more complex cases you may need to consider a
condition_variable
or other more sophisticated signaling mechanism. 对于更复杂的情况,您可能需要考虑
condition_variable
或其他更复杂的信令机制。
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this] () { work(); }) {}
void cancel() { running_ = false; }
~S() {
if ( running_ )
cancel();
if ( thread_.joinable() )
thread_.join();
}
private:
void work() {
while ( running_ ) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
Live demo: http://coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1 现场演示: http : //coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.