c++ - 尝试使用移动语义创建线程 guard

标签 c++ multithreading parallel-processing

标题很容易说明。我试图得到一个最小的线程保护工作示例,它也可以支持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/

相关文章:

C++ 未知名称类型

c++ - 声明从抽象类继承的继承抽象方法是否有任何性能问题?

c++ - cuda随机数并不总是返回0和1

java - 使用 ServerSockets 和套接字的多线程 JUnit 测试

c++ - 有什么方法可以将右值/临时对象传递给需要非成本引用的函数?

c++ - C++中执行线程的奇怪顺序

bash - 如何读取 2 列文件并将每列作为 GNU 并行的配对输入传递

tensorflow - 通过 Tensorflow 利用多个 CPU 内核

concurrency - 如果只有很少的进程可以并行执行,那么能够有效地生成数十个进程有什么意义呢?

c++ - 多线程环境下初始化的内存语义(C++)