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

时间:2012-02-08 08:39:52

标签: c++ multithreading

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

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&lt; _Result,_Functor(_Bound_args   ...)&gt; :: __ call(std :: tuple&lt; _Args ...&gt;&amp;&amp;,std :: _ Index_tuple&lt; _Indexes   ...&gt;,typename std :: _ Bind_result&lt; _Result,_Functor(_Bound_args   ...)&gt; :: __ enable_if_void&lt; _Res&gt; :: type)[with _Res = void,_ Args = {},   int ..._ Indexes = {},_ Result = void,_Functor = test *,_ Bound_args =   {},typename std :: _ Bind_result&lt; _Result,_Functor(_Bound_args   ...)&gt; :: __ enable_if_void&lt; _Res&gt; :: type = int]':   /usr/include/c++/4.6/functional:1378:24:实例化   'std :: _ Bind_result&lt; _Result,_Functor(_Bound_args ...)&gt; :: result_type   std :: _ Bind_result&lt; _Result,_Functor(_Bound_args   ...)&gt; :: operator()(_ Args&amp;&amp; ...)[with _Args = {},_ Result = void,   _Functor = test *,_ Bound_args = {},std :: _ Bind_result&lt; _Result,_Functor(_Bound_args ...)&gt; :: result_type = void]'/usr/include/c++/4.6/thread:117:13:从实例化“无效   std :: thread :: _ Impl&lt; _Callable&gt; :: _ M_run()[with _Callable =   std :: _ Bind_result]'test.cpp:28:1:实例化   这里/usr/include/c++/4.6/functional:1287:4:错误:   '((std :: _ Bind_result *)this) - &gt; std :: _ Bind_result :: _ M_f'不能用作函数

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

3 个答案:

答案 0 :(得分:3)

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

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

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

您无法拨打thisthis是指向当前对象的指针,它不可调用。

您需要将成员函数或其他函数传递给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 :(得分:3)

许多修正:

#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()));
    

答案 2 :(得分:2)

试试这个。

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