标题很容易说明。我试图得到一个最小的线程保护工作示例,它也可以支持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;
}
目前遇到障碍。 std::invoke,找不到匹配的重载函数,我看不到这里缺少什么。
最佳答案
您需要将int
转换为std::string
:
tp[i] = ThreadGuard(std::thread(doWork, std::to_string(i)));
您也不需要编写自己的move构造函数和move赋值运算符。使用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;
};
您还可以使转换构造函数接受线程构造函数参数并直接转发它们: template<typename...Args>
explicit ThreadGuard(Args&&... args): t(std::forward<Args>(args)...)
{}
这样可以像这样创建它:tp[i] = ThreadGuard(doWork, std::to_string(i));
另外值得注意的是:在C++ 20中,添加了 std::jthread
,该join()
在销毁时自动生成。
关于c++ - 尝试使用移动语义创建线程 guard ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63291544/