Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to terminate a std::thread?

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
}
like image 652
tobin Avatar asked Jul 23 '16 05:07

tobin


People also ask

Can we terminate a thread?

By using a flag we can stop a thread whenever we want to and we can prevent unwanted run-time errors. Using a volatile boolean flag: We can also use a volatile boolean flag to make our code thread safe.

How do you stop a thread from running in C++?

You could call std::terminate() from any thread and the thread you're referring to will forcefully end. You could arrange for ~thread() to be executed on the object of the target thread, without a intervening join() nor detach() on that object.

How do you destroy a detached thread in C++?

Do not detach the thread. Instantiate it in main(). Add a bool value, and a std::mutex , the bool gets initialized to false. In main(), before exiting: lock the mutex, set the bool flag to true , unlock the mutex, then join the thread.

How do you create and terminate a thread?

To create a thread, either we declare a variable of that thread class or use new to actually create one. After this, the thread is created. To run it, we have to call the method ThreadFunc() of that thread. When the execution of a thread reaches a return point or executes the call to Exit(), it terminates.


1 Answers

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;
};
like image 74
for_stack Avatar answered Oct 16 '22 16:10

for_stack