C ++方法线程

时间:2015-03-16 18:32:51

标签: c++ c++11

我想为类中的方法创建一个线程。我写了这个:

class Program
{
    public:
        Program();
        void render();
};

Program::Program()
{
    thread t(render);
}

void Program::render()
{
    cout << "Hello" << endl;
}

这给了我这个错误信息:

“错误C3867:'Program :: render':函数调用缺少参数列表;使用'&amp; Program :: render'创建指向成员的指针”

当我写这篇文章时:

thread t(&Program::render);

它说:

1>c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1149) : error C2064 : term does not evaluate to a function taking 0 arguments
1>          class does not define an 'operator()' or a user defined conversion operator to a pointer - to - function or reference - to - function that takes appropriate number of arguments
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::operator ()<>(void)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::operator ()<>(void)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(192) : while compiling class template member function 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)'
1>          with
1>[
    1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
        1>]
        1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(187) : see reference to function template instantiation 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)' being compiled
        1>          with
        1>[
            1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                1>]
                1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(205) : see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
                1>          with
                1>[
                    1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                        1>]
                        1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thread(49) : see reference to function template instantiation 'void std::_Launch<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>>(_Thrd_t *,_Target &&)' being compiled
                        1>          with
                        1>[
                            1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                                1>]
                                1>          c:\users\erik\documents\visual studio 2013\projects\c++gameengine\c++gameengine\program.cpp(16) : see reference to function template instantiation 'std::thread::thread<void(__thiscall Program::* )(void),>(_Fn &&)' being compiled
                                1>          with
                                1>[
                                    1>              _Fn = void(__thiscall Program::*)(void)
                                        1>]

我不太明白出了什么问题。你能解释一下并给我一个解决方案吗?

3 个答案:

答案 0 :(得分:4)

render是一个非静态成员函数,因此需要一个对象来调用它。您需要将它包装在一个小函数对象中,以便在Program上调用它。根据品味,有两种方便的方法:

thread t(&Program::render, this);
thread t([this]{render();});

下一个问题是该线程是构造函数的本地线程,因此会立即销毁。你不能破坏一个线程对象而不加入它(等待线程完成)或分离它。所以要么成为会员,要么稍后加入;或者在返回之前将其拆下。

答案 1 :(得分:1)

您应该使您的类成员函数static,或使用std::bind()将函数传递给std::thread实例。

另请注意,您的std::thread t;变量是构造函数的本地变量。你将以这种方式松开与该线程的任何连接,并且在构造函数的范围结束后不再对它进行控制。

答案 2 :(得分:1)

你可以这样做:

Program::Program()
{
    std::thread t(&Program::render, this);
    t.join();
}

然而,这没有任何结果,因为它只是阻塞直到函数调用返回。也许你想分离线程?

std::thread(&Program::render, this).detach();

现在你需要建立自己的逻辑来告诉线程什么时候停止。

或者你让线程成为类成员:

struct Program
{
    void render();

    Program() : render_thread_(&Program::render, this) {}
    ~Program() { render_thread_.join(); }

    std::thread render_thread_;
};