首页 文章

std :: thread,在'this'上启动线程(来自类本身)

提问于
浏览
3

我正在尝试创建一个类,它启动其成员方法之一的线程实例 . 当我做主要时:

test myinstance;
std::thread mythread(myinstance);

然后事情编译 . 但使用以下结构:

#include <stdio.h>
#include <unistd.h>
#include <thread>

class test
{
        std::thread *pt;
public:
        test()
        {
                pt = new std::thread(this);
        }

        void operator()() const
        {
                printf("thread start\n");
                sleep(5);
                printf("thread end\n");
        }
};

int main(int arg, char *argv[])
{
        test ptest;
        sleep(10);

        return 0;
}

我收到以下错误:

folkert @ here:〜$ g -std = c 0x test.cpp在/ usr / include / c /4.6/thread:39:0中包含的文件中,来自test.cpp:3:/ usr / include / c /4.6 / functional:在成员函数'void std :: _ Bind_result <_Result,_Functor(_Bound_args ...)> :: __ call(std :: tuple <_Args ...> &&,std :: _ Index_tuple <_Indexes ...>, typename std :: _ Bind_result <_Result,_Functor(_Bound_args ...)> :: __ enable_if_void <_Res> :: type)[with Res = void, Args = {},int ..._ Indexes = {},_ Result = void, Functor = test *, bind_args = {},typename std :: _ Bind_result <_Result,_Functor(_Bound_args ...)> :: __ enable_if_void <_Res> :: type = int]':/ usr / include / c /4.6/functional :1378:24:实例化自'std :: _ Bind_result <_Result,_Functor(_Bound_args ...)> :: result_type std :: _ Bind_result <_Result,_Functor(Bound_args ...)> :: operator()( Args && .. . )[with Args = {}, Result = void,Functor = test *, bind_args = {},std :: _ Bind_result <_Result,_Functor(_Bound_args ...)> :: result_type = void]'/ usr / include / c /4.6/thread:117:13:从中实例化'void std :: thread :: _ Impl <_Callable> :: _ M_run()[with _Callable = std :: _ Bind_result]'test.cpp:28:1:从这里实例化/ usr / include / c /4.6/functional:1287 :4:错误:'((std :: _ Bind_result *)this) - > std :: _ Bind_result :: _ M_f'不能用作函数

所以我的猜测是它不会这样工作 . 我现在的问题是:我如何使用std :: thread让一个类启动一个自己的方法的线程?

3 回答

  • 3

    std::thread 的构造函数之一如下所示:

    template<typename Callable>
        explicit thread(Callable func);
    

    这要求您传递 callable 的内容,这意味着可以使用 operator() 调用它 . 您传递给 std::thread 的内容不可调用 .

    你不能叫 this . this 是指向当前对象的指针,它不可调用 .

    您需要将成员函数或其他函数传递给 std::thread 构造函数 .

    你也可以创建一个仿函数并传递它,因为它是可调用的 .

    编辑:刚刚注意到确实超载 operator() ,要调用它,你已经做了以下事情:

    test t;
      std::thread my_thread(t); //invokes operator() on test.
    
    //also remove this statement from your ctor:  pt = new std::thread(this);
    
  • 1

    许多修复:

    #include <iostream>
    #include <thread>
    
    struct test
    {
        void operator()() const
        {
            std::cout << "thread start\n";
            sleep(5);
            std::cout << "thread end\n";
        }
    };
    
    int main(int arg, char *argv[])
    {
        std::thread pt(std::move(test()));
    
        pt.join();
        return 0;
    }
    

    修复

    • 关注点分离(你可以在没有线程的情况下运行 test ,是的!)

    • 泄漏了std :: thread实例(内存资源)

    • 不(确定地)等待线程完成;即使你认为你知道睡眠会持续更长时间,这也是UB

    • 注意如何通过移动来避免ptest的本地/副本 . 从技术上讲, std::move 在那里是多余的,但我喜欢具体的东西,你会遇到most vexing parse

    std::thread pt((test()));
    
  • 3

    试试这个 .

    pt = new std :: thread(std :: ref(* this));

相关问题