C++方法线程

C++ Method thread

本文关键字:线程 方法 C++      更新时间:2023-10-16

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

class Program
{
    public:
        Program();
        void render();
};
Program::Program()
{
    thread t(render);
}
void Program::render()
{
    cout << "Hello" << endl;
}

这给了我这个错误消息:

"错误 C3867: '程序::渲染':函数调用缺少参数列表;使用"&Program::render"创建指向成员的指针"

当我写这个时:

thread t(&Program::render);

它说:

1>c:program files(x86)microsoft visual studio 12.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludefunctional(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.0vcincludethrxthread(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.0vcincludethrxthread(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.0vcincludethrxthread(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.0vcincludethrxthread(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.0vcincludethrxthread(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.0vcincludethread(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:userserikdocumentsvisual studio 2013projectsc++gameenginec++gameengineprogram.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>]

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

render是一个

非静态成员函数,因此它需要一个对象来调用它。您需要将其包装在一个小函数对象中才能在Program上调用它。根据口味,有两种方便的方法可以做到这一点:

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

下一个问题是线程是构造函数的本地线程,因此会立即销毁。在未加入线程对象(等待线程完成)或分离线程对象的情况下,不得销毁该对象。因此,要么使其成为会员,以便以后可以加入;或在返回之前将其拆下。

你可以这样做:

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_;
};

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

另请注意,std::thread t;变量是构造函数的局部变量。您将以这种方式失去与该线程的任何连接,并且在构造函数的作用域结束后不再控制它。