How to terminate a std::thread?

tobin picture tobin · Jul 23, 2016 · Viewed 8.2k times · Source

I am currently developing a program that needs to download some images from the socket server,and the downloading work will execute a long time. So, I create a new std::thread to do that.

Once it's downloaded,the std::thread will call a member function of current Class, but this Class is likely to have been released. So, I got a exception.

How to solve this problem?

void xxx::fun1()
{
   ...
}
void xxx::downloadImg()
{
 ...a long time
  if(downloadComplete)
  {
   this->fun1();
  }
}
void xxx::mainProcees()
{
  std::thread* th = new thread(mem_fn(&xxx::downloadImg),this);
  th->detach();
  //if I use th->join(),the UI will be obstructed
}

Answer

for_stack picture for_stack · Jul 23, 2016

Don't detach the thread. Instead, you can have a data member that hold a pointer to the thread, and join the thread in destructor.

class YourClass {
public:
    ~YourClass() {
        if (_thread != nullptr) {
            _thread->join();
            delete _thread;
        }
    }
    void mainProcees() {
        _thread = new thread(&YourClass::downloadImg,this);
    }
private:
    thread *_thread = nullptr;
};

UPDATE

Just as @milleniumbug pointed out, you don't need dynamic allocation for the thread object, since it is movable. So the other solution is as follows.

class YourClass {
public:
    ~YourClass() {
        if (_thread.joinable())
            _thread.join();
    }
    void mainProcess() {
        _thread = std::thread(&YourClass::downloadImg, this);
    }
private:
    std::thread _thread;
};