线程作为成员变量

时间:2017-08-09 23:12:14

标签: c++ multithreading

我希望将一个线程保存为类的成员变量。我想在内部启动线程' start'方法,并停止内部的线程'停止'方法。我也想确保线程加入,无论是否停止'方法被调用。

我设计了以下代码,使用shared_ptr自定义删除器用于连接线程并删除指向线程的指针,但我不是100%确定它是否完全正确。

请对此发表评论。一切都好吗?或者可能有更好的方法如何做到这一点(例如使用unique_ptr或设计其他RAII类)?

#include <thread>
#include <iostream>
#include <memory>
using namespace std::chrono_literals;

void fun() { std::cout << "inside thread\n"; std::this_thread::sleep_for(1s); }

class A
{
public:
    A() : pT(nullptr) {}

    void start()
    {
        std::cout << "starting...\n";
        pT.reset(new std::thread(fun), [](auto p) {
            if (p->joinable()) 
            { 
                std::cout << "joining thread\n";
                p->join(); 
            }
            std::cout << "deleting thread\n"; 
            delete p;
       });
    }

    void stop()
    {
        std::cout << "stopping...\n";
        pT.reset();
    }

private:
    std::shared_ptr<std::thread> pT;
};
int main()
{
    A a;
    a.start();
    std::this_thread::sleep_for(2s);
    a.stop();

    return 0;
}

输出正确:

starting...
inside thread
stopping...
joining thread
deleting thread

1 个答案:

答案 0 :(得分:0)

在我的情况下,我喜欢控制什么是创造以及什么时候被摧毁。所以,我的建议是:

您可以将线程指针添加为类的成员,并检查它是否已完成,因为我在此示例中显示:

class A{

   std::thread *pThread = NULL; \\ Thread Pointer
   //...
public:
   A();
   ~A();
   void start();
   void stop();
}

并将其用作:

void start()
{
    if(pThread == NULL) 
    {
       pThread = new thread(fun); //Create the thread and store its reference
    }
}

~A()
{
    if (pThread != NULL)
    {
        if(pThread->joinable()) \\Wait until the thread has been finished
            pThread->join();
        delete pThread; \\IMPORTANT, release the memory. 
    }
}

在这个示例中,我使用线程来同步Class的销毁,在线程完成之前不会销毁它。

注意:如果要将某个类的方法用作运行该线程的函数,可以使用std::bind

  

此外,您可以将智能指针用作unique_ptr而不是std::thread,就像我在此示例中所做的那样。在这种情况下,当类被销毁时,内存将被释放,因此请确保在删除此指针之前完成线程o离开上下文(Class)。