如何创建运行抽象 class 成员函数的 std::thread?

How do I create an std::thread that runs a member function of an abstract class?

我有一些想法:

class Parent
{
private:
    std::thread t1;
protected:
    void ThreadFunction()
    {
        while(true)
        {
            SpecializedFunction();
        }
    }
    void CreateThread()
    {
        t1 = std::thread(&Parent::ThreadFunction, *this);
    }
    virtual void SpecializedFunction() = 0;
public:
    void Run()
    {
        CreateThread();
    }
}

class Child1 : public Parent
{
protected:
    void SpecializedFunction()
    {
        //code
    }
}

class Child2 : public Parent
{
protected:
    void SpecializedFunction()
    {
        //code
    }
}

但是我有编译错误(如果我注释线程创建行它编译)。它说它不能专门化衰减方法。我认为问题要么是 Parent 是抽象的,要么是线程函数是受保护的,但我不确定。您能否提出 workaround/a 解决方案?

谢谢!

    t1 = std::thread(&Parent::ThreadFunction, *this);

这将创建 *this 的副本和 运行 副本上的成员函数。在您的情况下失败了,因为您无法创建摘要的副本 class,但制作副本可能不是您想要的。

向运行现有对象上的线程传递一个指针:

    t1 = std::thread(&Parent::ThreadFunction, this);

或(自LWG 2219的决议)参考:

    t1 = std::thread(&Parent::ThreadFunction, std::ref(*this));

作为T.C。在上面的评论中说,您必须确保对象的生命周期不会在新线程仍在 运行ning 时结束。你可以通过在析构函数中加入它来做到这一点:

~Parent() { if (t1.joinable()) t1.join(); }

(如果你在 std::thread 被销毁之前不加入,你的程序将立即终止!)

这仍然不是很安全,因为它只能确保 base class 在线程仍然 运行ning 时不被破坏,但是线程可能正在访问派生 class,因此您可能需要确保线程已加入 derived 析构函数。