Как разбудить std::thread, пока он спит?
Опубликовано: 14 Сентября, 2022
В этой статье мы обсудим, как разбудить std::thread , пока он спит. Известно, что поток не может быть завершен, когда он спит. Таким образом, он просыпается с помощью команды:
std::condition_variable
Ниже приведен псевдокод для реализации того же самого:
C++
// Custom Class struct MyClass { // Constructor MyClass() : my_thread([ this ]() { this -> thread (); }) { } // Destructor ~MyClass() { { std::lock_guard<std::mutex> l(m_); stop_ = true ; } c_.notify_one(); my_thread.join(); } // Function that implements the // thread void thread () { while ( this ->wait_for(std::chrono::minutes(2))) SendStatusInfo(some_info); } // Function to returns false when // the thread is stopped template < class Duration> bool wait_for(Duration duration) { std::unique_lock<std::mutex> l(m_); return !c_.wait_for(l, duration, [ this ]() { return stop_; }); } // Conditions Variable std::condition_variable c_; std::mutex m_; bool stop_ = false ; std:: thread my_thread; }; |
Ниже приведен еще один пример, иллюстрирующий то же самое:
std::promise/std::future
Приведенную выше команду можно использовать как более простую альтернативу предыдущему методу. В этом случае Future не подвержен ложным пробуждениям и не требует мьютекса для синхронизации. Ниже приведен псевдокод для реализации того же самого:
C++
// Promise Condition std::promise< void > pr; // Start the thread std:: thread thr{ [fut = pr.get_future()]{ // Iterate until the condition // break while ( true ){ if (fut.wait_for(std::chrono::minutes(2)) != std::future_status::timeout) return ; } } } ; // When ready to stop pr.set_value(); // Join the thread thr.join(); |
Ниже приведена программа, иллюстрирующая приведенные выше концепции:
C++
// C++ program to illustrate the waking // of the thread while it is sleeping #include <bits/stdc++.h> using namespace std; std::deque< int > q; std::mutex mu; std::condition_variable cond; // Function to create the thread 1 void function_1() { // Initialize a counter variable int count = 10; // Iterate until count is positive while (count > 0) { // Mutex std::unique_lock<mutex> locker(mu); // Push the current count in // the dequeue q.push_front(count); locker.unlock(); cond.notify_one(); // If there is any waiting thread // then notify that thread std::this_thread::sleep_for( chrono::seconds(1)); // Decrement the count count--; } } // Function to create the thread 2 void function_2() { // Initialize a variable to get // the data from the deque int data = 0; while (data != 1) { std::unique_lock<mutex> locker(mu); cond.wait(locker, []() { return !q.empty(); }); // False Waking of thread data = q.back(); q.pop_back(); locker.unlock(); // Print the message cout << "t2 got a value from" " t1" << data << "
" ; } } // Driver Code int main() { // Create thread 1 std:: thread t1(function_1); // Create thread 2 std:: thread t2(function_2); // Join the threads t1.join(); t2.join(); return 0; } |
Выход: