尝试使用移动语义创建线程保护

Kro*_*hon 1 c++ parallel-processing multithreading

标题是不言自明的。我正在尝试获得一个线程保护的最小工作示例,该示例还可以支持 std::threads 具有的移动语义。

#include <iostream>
#include <thread>
#include <vector>
#include <functional>

class ThreadGuard {
public:
    explicit ThreadGuard(std::thread input): t(std::move(input))
    {}
    ~ThreadGuard(){
        if(t.joinable()){
            t.join();
        }
    }
    ThreadGuard(ThreadGuard const& t) = delete;
    ThreadGuard& operator=(ThreadGuard const&) = delete;

    ThreadGuard& operator=(ThreadGuard&& out){
        this->t = out.transfer();
        return *this;
    }
    std::thread transfer(){
        return std::move(t);
    }
private:
    std::thread t;
};

void doWork(std::string input){
    std::cout << input << std::endl;
}

static const auto numThreads = 4;
int main()
{
    std::vector<ThreadGuard> tp;
    tp.reserve(numThreads);
    for(auto i = 0 ; i < numThreads; ++i){
        tp[i] = ThreadGuard(std::thread(doWork, i));
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

目前遇到路障。std::invoke,找不到匹配的重载函数,我看不到这里缺少什么。

Ted*_*gmo 5

您需要将 转换intstd::string

tp[i] = ThreadGuard(std::thread(doWork, std::to_string(i)));
Run Code Online (Sandbox Code Playgroud)

您也不需要编写自己的移动构造函数和移动赋值运算符。使用default

class ThreadGuard {
public:
    explicit ThreadGuard(std::thread&& input): t(std::move(input))
    {}
    ThreadGuard(ThreadGuard const& t) = delete;
    ThreadGuard(ThreadGuard&&) noexcept = default;
    ThreadGuard& operator=(ThreadGuard const&) = delete;
    ThreadGuard& operator=(ThreadGuard&&) noexcept = default;  
    ~ThreadGuard(){
        if(t.joinable()){
            t.join();
        }
    }

private:
    std::thread t;
};
Run Code Online (Sandbox Code Playgroud)

您还可以使转换构造函数接受线程构造函数参数并直接转发它们:

    template<typename...Args>
    explicit ThreadGuard(Args&&... args): t(std::forward<Args>(args)...)
    {}
Run Code Online (Sandbox Code Playgroud)

这将允许它像这样创建:

tp[i] = ThreadGuard(doWork, std::to_string(i));
Run Code Online (Sandbox Code Playgroud)

还值得注意的是:在 C++20std::jthread中添加了join()自动销毁。

  • 1+ 完整答案。 (2认同)