2016-07-23 5 views
5

В настоящее время я разрабатываю программу, которая должна загружать некоторые изображения с сервера сокетов, а работа по загрузке будет выполняться долгое время. Итак, я создаю новый std::thread, чтобы сделать это.Как завершить std :: thread?

После его загрузки 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

Добро пожаловать в переполнение стека! Я отредактировал ваш вопрос, насколько я мог догадаться о вашей проблеме. Однако добавьте объяснение кода и описания, чтобы увидеть больше людей со знанием предмета. Измените конкретное сообщение об ошибке, с которым вы сталкиваетесь, в случае необходимости определить конкретную проблему. Удачи! – manetsus

+2

Почему вы не используете 'std :: future '? – Superlokkus

+1

Возможный дубликат [C++ 0x thread interruption] (http://stackoverflow.com/questions/2790346/c0x-thread-interruption) – kfsone

ответ

3

Не отсоединяйте резьбу. Вместо этого вы можете иметь элемент данных, который содержит указатель на thread и join поток в деструкторе.

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 в этом случае вам нужно выполнить некоторую синхронизацию между основным потоком и потоком загрузки. Например, вы можете иметь флаг «stop». Загружаемый поток проверяет флаг каждые 1 секунду, если флаг установлен, а затем завершает загрузку. В деструкторе сначала установите флаг «стоп», затем присоедините поток. –

+0

спасибо за вашу помощь. Он работает сейчас. Если функция «downloadImg» является интерфейсом статической лирбрары, что мне делать? – tobin