使用C++中的RAII在线程包装类中移动语义

我试图让一个围绕 std::thread 的 RAII 包装类在 C++ 中工作。

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

using std::cout;
using std::endl;

void threadFunction()
{
    for (int i = 0; i < 20; ++i) {
        cout << "thread function pointer executing..." << i << endl;
    }
}



// RAII wrapper that supports automatic join
class ThreadJoinRAII
{
    std::thread thread_;
public:
    ThreadJoinRAII(std::thread&& t):thread_(std::move(t)) 
    // ThreadJoinRAII()
    {
        cout << "ThreadJoinRAII ctor" << endl;
    }

    //ThreadJoinRAII(const ThreadJoinRAII& other) = delete;
    //ThreadJoinRAII& operator=(const ThreadJoinRAII& other) = delete;

    //ThreadJoinRAII(ThreadJoinRAII&& other):thread_(std::move(other.thread_))
    //{
    //    cout << "ThreadJoinRAII move ctor" << endl;
    //}
    //ThreadJoinRAII& operator=(ThreadJoinRAII&& other)
    //{
    //    cout << "ThreadJoinRAII move op" << endl;
    //    thread_ = std::move(other.thread_);
    //    return *this;
    //}
    
    ~ThreadJoinRAII()
    {
        cout << "in ThreadJoinRAII dtor" << endl;
        if (thread_.joinable()) { 
            thread_.join();
            cout << "join thread id = " << thread_.get_id() << endl;
        } else {
            cout << "thread not joinable.Something ctor" << endl;
    }

};


void testRAII()
{
    ThreadJoinRAII t1(std::move(std::thread(threadFunction))); // prints ThreadJoinRAII ctor
    ThreadJoinRAII t2(std::thread(threadFunction)); // prints nothing
    Something s1(std::vector<int>(3, 4)); // prints Something ctor
}

int main(int argc, char* argv[])
{
    testRAII();
    return 0;
}

问题是那一t2testRAII()没有打印任何内容。那部分我不明白。我尝试添加/删除复制操作和移动操作,但它们没有任何区别。

我的问题是:

  1. 不是std::thread(threadFunction)已经是右值了testRAII()吗?为什么我必须移动它才能让构造函数工作?
  2. t2如果未使用提供的构造函数,将调用哪些代码?我没有看到 ThreadJoinRAII ctor 打印出来。
  3. s1行打印出“Something ctor”。t2和 和有s1什么区别?是std::thread右值区别对待?

顺便说一句,我在 Ubuntu 20.04 LTS 上用 g++ 9.3 和g++ -std=c++17 -o mt mt.m.cpp -lpthread. mt.m.cpp是我的文件名。

回答

乍一看它可能不像,但它t2是一个函数原型,而不是一个变量声明(搜索“最令人烦恼的解析”)。

您可以通过添加一些括号将其更改为变量:

ThreadJoinRAII t2((std::thread(threadFunction)));

然后它会调用你的ThreadJoinRAII构造函数。

  • Or use the curly brace version: `ThreadJoinRAII t2{std::thread(threadFunction)};`

以上是使用C++中的RAII在线程包装类中移动语义的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>