在线程之间移动向量

fly*_*lyx 5 c++ multithreading move-semantics c++11

我有一个线程,通过这样的公共接口不断收集数据项:

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;
};
Run Code Online (Sandbox Code Playgroud)

检索项目还应清除线程的项目列表.我返回一个右值,以便在调用端调用移动构造函数.当然,检索项应该是线程安全的,因此实现如下所示:

std::vector<MyThread::Item>&& MyThread::items() {
    std::lock_guard<std::mutex> lock(itemMutex);
    return std::move(currentItems);
}
Run Code Online (Sandbox Code Playgroud)

我认为锁定在这里发布得太早:函数返回rvalue'd向量,但是当std::lock_guard销毁并释放互斥锁时,移动构造函数不一定会被调用.所以从我的理解来看,这不是线程安全的.我对吗?如何使其线程安全?

Sea*_*ean 9

你是对的,它不是线程安全的,因为在方法返回后会发生移动,此时锁定将被释放.要修复它,只需将向量移动到局部变量并返回:

std::vector<MyThread::Item> MyThread::items() 
{
    std::lock_guard<std::mutex> lock(itemMutex);
    return std::vector<MyThread::Item>(std::move(currentItems));
}
Run Code Online (Sandbox Code Playgroud)

  • @CouchDeveloper`return currentItems;`仅当`currentItems`是函数局部变量时才有效.这是一个数据成员,因此需要`std :: move`. (3认同)