2016-07-23 75 views
5

我目前正在开发一个程序,需要从套接字服务器下载一些图片,并且下载工作将会执行很长时间。所以,我创建了一个新的std::thread来做到这一点。如何终止一个std ::线程?

下载后,std::thread会调用当前类的成员函数,但该类很可能已经发布。所以,我有一个例外。

如何解决这个问题?

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 
} 
+0

欢迎来到Stack Overflow!我尽可能地猜测你的问题,然后编辑你的问题。但是,添加对代码和描述的解释,以便更多具有该主题知识的人员可以看到它。如果需要识别特定问题,请编辑您遇到的特定错误消息。祝你好运! – manetsus

+2

为什么不使用'std :: future '? – Superlokkus

+1

[C++ 0x线程中断]的可能重复(http://stackoverflow.com/questions/2790346/c0x-thread-interruption) – kfsone

回答

3

请勿分离线。相反,您可以拥有一个数据成员,该成员持有指向threadjoin析构函数的指针。

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

UPDATE

正如@milleniumbug指出的那样,你并不需要动态分配的thread对象,因为它是可移动的。所以另一个解决方案如下。

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

谢谢,我已经尝试过这种方法,但是这是一个特殊的场合,“YourClass”是一个游戏场景,用户可以随时弹出这个场景,如果你这样做,会阻碍很长一段时间用户弹出这个场景 – tobin

+0

In在这种情况下,你必须在主线程和你的下载线程之间做一些同步。例如,您可以拥有“停止”标志。下载线程每隔1秒检查一次标志,如果标志已设置,则退出下载。在析构函数中,首先设置“停止”标志,然后加入该线程。 –

+0

感谢您的帮助,它现在可以工作。如果“downloadImg”函数是一个静态lirbrary的接口,我该怎么做? – tobin