可以在 C++ 11 中移动线程对象是否合理?
Is that the thread object can be moved in C++ 11 reasonable?
在C++11中,可以移动线程对象。众所周知,我们创建的每个线程都拥有一个仿函数。显然,移动一个其仿函数还没有被执行的线程是合理的。但是移动正在调用或已经执行了一段时间的仿函数的线程呢?
更进一步,如果我实现线程包装器 class,例如:
//noncopyable is a tag class of which copy constructor and copy assignment are deleted.
class Thread:noncopyable{
private:
using ThreadFunc = std::function<void()>;
bool started_; //used to mark whether the functor executes or not
std::thread thread_;
CountDownLatch latch_;
std::string name_;
ThreadFunc func_;
...
public:
Thread(ThreadFunc func, const std::string& name)
:func_(std::move(func)),name_(name){}
...
}
而且我想像线程对象那样实现Thread的移动操作。在移动操作之前检查 started_
会是一个更好的选择吗?(虽然我认为它不是十比一)喜欢:
Thread& Thread::operation=(Thread&& rhs) noexcept{
if(this != &rhs && !started_){
//do something
}
return *this;
}
Thread::Thread(Thread&& rhs) noexcept{
//do something
}
A std::thread
没有正式拥有构造它的函子。相反,仿函数由构造函数启动(在目标线程中)的 std::invoke
调用持有。
所以移动 std::thread
不需要,也不会移动仿函数。只要线程在执行,仿函数就作为局部变量存在。
在C++11中,可以移动线程对象。众所周知,我们创建的每个线程都拥有一个仿函数。显然,移动一个其仿函数还没有被执行的线程是合理的。但是移动正在调用或已经执行了一段时间的仿函数的线程呢?
更进一步,如果我实现线程包装器 class,例如:
//noncopyable is a tag class of which copy constructor and copy assignment are deleted.
class Thread:noncopyable{
private:
using ThreadFunc = std::function<void()>;
bool started_; //used to mark whether the functor executes or not
std::thread thread_;
CountDownLatch latch_;
std::string name_;
ThreadFunc func_;
...
public:
Thread(ThreadFunc func, const std::string& name)
:func_(std::move(func)),name_(name){}
...
}
而且我想像线程对象那样实现Thread的移动操作。在移动操作之前检查 started_
会是一个更好的选择吗?(虽然我认为它不是十比一)喜欢:
Thread& Thread::operation=(Thread&& rhs) noexcept{
if(this != &rhs && !started_){
//do something
}
return *this;
}
Thread::Thread(Thread&& rhs) noexcept{
//do something
}
A std::thread
没有正式拥有构造它的函子。相反,仿函数由构造函数启动(在目标线程中)的 std::invoke
调用持有。
所以移动 std::thread
不需要,也不会移动仿函数。只要线程在执行,仿函数就作为局部变量存在。