2016-07-23 34 views
5

Obecnie rozwijam program, który musi pobrać kilka obrazów z serwera gniazd, a praca pobierania będzie trwała długo. Tak więc tworzę nowy std::thread, aby to zrobić.Jak przerwać std :: thread?

Po pobraniu, std::thread wywoła funkcję członka bieżącej klasy, ale ta klasa prawdopodobnie została zwolniona. Tak, mam wyjątek.

Jak rozwiązać ten 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 
} 
+0

Witamy w Stack Overflow! Zmieniłem twoje pytanie tak daleko, jak mogłem odgadnąć twój problem. Dodaj jednak wyjaśnienie kodu i opisu, aby zobaczyć je więcej osób mających wiedzę na ten temat. Dokonaj edycji w konkretnym komunikacie o błędzie, który napotykasz, jeśli jest to konieczne, aby zidentyfikować konkretny problem. Powodzenia! – manetsus

+2

Dlaczego nie używasz 'std :: future '? – Superlokkus

+1

Możliwy duplikat [przerwania wątku C++ 0x] (http://stackoverflow.com/questions/2790346/c0x-thread-interruption) – kfsone

Odpowiedz

3

Nie odłączaj nici. Zamiast tego możesz mieć element danych zawierający wskaźnik do thread i join wątku w destruktorze.

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

UPDATE

Podobnie jak @milleniumbug wskazał, nie trzeba dynamiczną alokację dla obiektu thread, ponieważ jest ruchomy. Inne rozwiązanie jest następujące.

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

Dzięki, wypróbowałem tę metodę, ale jest to specjalna okazja, "YourClass" to scena gry, użytkownicy mogą w każdej chwili otworzyć tę scenę, jeśli to zrobicie, będzie to utrudniało długi czas, kiedy użytkownicy będą ją wyświetlać. – tobin

+0

In w tym przypadku musisz wykonać synchronizację między głównym wątkiem a wątkiem pobierania. Na przykład możesz mieć flagę "stop". Wątek pobierania sprawdza flagę co 1 sekundę, jeśli flaga została ustawiona, a następnie wyjdź z pobierania. W destruktorze ustaw najpierw flagę "stop", a następnie dołącz do wątku. –

+0

dziękuję za pomoc, działa teraz. Co mam zrobić, jeśli funkcja "downloadImg" jest interfejsem statycznej lirbrary? – tobin