2016-10-20 2 views
2

Wie kann ich meinen gesponnenen Thread im Destruktor von Bar beenden (ohne warten zu müssen, bis der Thread aus dem Schlaf aufgewacht ist)?Einen std :: thread beenden, der in einer Endlosschleife läuft

class Bar { 

public: 

Bar() : thread(&Bar:foo, this) { 
} 

~Bar() { // terminate thread here} 



... 

void foo() { 
    while (true) { 
    std::this_thread::sleep_for(
    std::chrono::seconds(LONG_PERIOD)); 

    //do stuff// 
    } 

} 

private: 
    std::thread thread; 

}; 
+0

Können Sie mit einem zeitgesteuerten Zustand schlafen anstatt auf einen harten Schlaf warten? –

+7

Verwenden Sie eine ['condition_variable'] (http://en.cppreference.com/w/cpp/thread/condition_variable). – Holt

+0

Sie können es nicht extern beenden, aber Sie können es trennen. – NathanOliver

Antwort

6

könnten Sie ein std::condition_variable verwenden:

class Bar { 
public: 
    Bar() : t_(&Bar::foo, this) { } 
    ~Bar() { 
     { 
      // Lock mutex to avoid race condition (see Mark B comment). 
      std::unique_lock<std::mutex> lk(m_); 
      // Update keep_ and notify the thread. 
      keep_ = false; 
     } // Unlock the mutex (see std::unique_lock) 
     cv_.notify_one(); 
     t_.join(); // Wait for the thread to finish 
    } 

    void foo() { 
     std::unique_lock<std::mutex> lk(m_); 
     while (keep_) { 
      if (cv_.wait_for(lk, LONG_PERIOD) == std::cv_status::no_timeout) { 
       continue; // On notify, just continue (keep_ is updated). 
      } 
      // Do whatever the thread needs to do... 
     } 
    } 

private: 
    bool keep_{true}; 
    std::thread t_; 
    std::mutex m_; 
    std::condition_variable cv_; 
}; 

Dies sollte Ihnen eine globale Vorstellung von dem, was Sie tun können:

  • Sie eine bool verwenden, um die Schleife zu steuern (mit geschütztem Lese- und Schreibzugriff unter Verwendung eines std::mutex);
  • Sie verwenden einen std::condition_variable, um den Thread aufzuwecken, um zu vermeiden, dass er auf LONG_PERIOD wartet.
+0

Hat das nicht eine Race Condition, wenn Sie: (2) check halten, (1) set false, (1) notify_one, (2) acquire lock, (2) wait (LONG_PERIOD) zur Benachrichtigung? –

+0

@MarkB Möglicherweise ... Dies ist eine grobe Idee, ich werde den Code aktualisieren, wenn ich kann. – Holt

+0

destructor sollte den Thread vor der Rückkehr – bobah

Verwandte Themen