我正在尝试创建一个类,它启动其成员方法之一的线程实例 . 当我做主要时:
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 回答
std::thread
的构造函数之一如下所示:这要求您传递 callable 的内容,这意味着可以使用
operator()
调用它 . 您传递给std::thread
的内容不可调用 .你不能叫
this
.this
是指向当前对象的指针,它不可调用 .您需要将成员函数或其他函数传递给
std::thread
构造函数 .你也可以创建一个仿函数并传递它,因为它是可调用的 .
编辑:刚刚注意到确实超载
operator()
,要调用它,你已经做了以下事情:许多修复:
修复
关注点分离(你可以在没有线程的情况下运行
test
,是的!)泄漏了std :: thread实例(内存资源)
不(确定地)等待线程完成;即使你认为你知道睡眠会持续更长时间,这也是UB
注意如何通过移动来避免ptest的本地/副本 . 从技术上讲,
std::move
在那里是多余的,但我喜欢具体的东西,你会遇到most vexing parse:试试这个 .
pt = new std :: thread(std :: ref(* this));