我有一个线程使用这样的公共(public)接口(interface)不断收集数据项:
class MyThread {
public:
class Item {
// ...
};
startup();
shutdown();
bool hasItems() const;
// retrieve collected items
std::vector<Item>&& items();
private:
std::mutex itemMutex;
std::vector<Item> currentItems;
};
检索项目还应该清除线程的项目列表。我返回一个右值,以便在调用方调用 move 构造函数。当然,检索项目应该是线程安全的,因此实现如下所示:
std::vector<MyThread::Item>&& MyThread::items() {
std::lock_guard<std::mutex> lock(itemMutex);
return std::move(currentItems);
}
我认为这里的锁释放得太早:该函数返回右值 vector ,但当 std::lock_guard
被销毁时,不一定会用它调用 move 构造函数并释放互斥体。所以据我了解,这不是线程安全的。我对吗?如何使其成为线程安全的?
最佳答案
你是对的,它不是线程安全的,因为 move 将在方法返回后发生,此时锁将被释放。要修复它,只需将 vector move 到一个局部变量中并返回它:
std::vector<MyThread::Item> MyThread::items()
{
std::lock_guard<std::mutex> lock(itemMutex);
return std::vector<MyThread::Item>(std::move(currentItems));
}
关于c++ - 在线程之间 move vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21280917/