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
}
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.
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.
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.
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.
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;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With