std::condition_variable
The condition variable std::condition_variable has wait and notify interfaces for inter-thread synchronization. As shown in the following figure, Thread 2 blocks on the wait interface, and Thread 1 notifies Thread 2 to continue execution via the notify interface.See the sample code for details:
#include<iostream>
#include<mutex>
#include<thread>
#include<queue>
std::mutex mt;
std::queue<int> data;
std::condition_variable cv;
auto start=std::chrono::high_resolution_clock::now();
void logCurrentTime()
{
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << elapsed << ":";
}
void prepare_data()
{
logCurrentTime();
std::cout << "this is " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;
for (int i = 0; i < 10; i++)
{
(i);
logCurrentTime();
std::cout << "data OK:" << i << std::endl;
}
//start to notify consume_data thread data is OK!
cv.notify_one();
}
void consume_data()
{
logCurrentTime();
std::cout << "this is: " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;
std::unique_lock<std::mutex> lk(mt);
//wait first for notification
(lk); //it must accept a unique_lock parameter to wait
while (!())
{
logCurrentTime();
std::cout << "data consumed: " << () << std::endl;
();
}
}
int main()
{
std::thread t2(consume_data);
//wait for a while to wait first then prepare data,otherwise stuck on wait
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::thread t1(prepare_data);
();
();
return 0;
}
output result
analyze
In the main thread, two threads are started to execute consume_data and prepare_data, where consume_data should be executed first to ensure that it waits before notifying, otherwise it will be deadlocked if it notifies first and then waits. First the consume_data thread is started after the first notification from thewait The queue is blocked and waits. The latter prepare_data thread writes 0-10 to the queue in turn, and after that writes 0-10 to the queue via thenotify_one Notify the consume_data thread to unblock and read 0-10 in turn.
std::future
std::future works with std::async to execute the code asynchronously, and then blocks the current thread waiting for the result via the wait or get interface. As shown in the following figure, the get or wait interface of the future interface in Thread 2 will block the current thread, and the new thread Thread1 opened by std::async asynchronously will notify Thread 1 to get the result after it finishes executing by storing the result in std::future and then continue executing.See the code below for details:
#include <iostream>
#include <future>
#include<thread>
int test()
{
std::cout << "this is " << __FUNCTION__ << " thread:" << std::this_thread::get_id() << std::endl;;
std::this_thread::sleep_for(std::chrono::microseconds(1000));
return 10;
}
int main()
{
std::cout << "this is " <<__FUNCTION__<<" thread:" << std::this_thread::get_id() << std::endl;;
//this will lanuch on another thread
std::future<int> result = std::async(test);
std::cout << "After lanuch a thread: "<< std::this_thread::get_id() << std::endl;
//block the thread and wait for the result
std::cout << "result is: " <<()<< std::endl;
std::cout << "After get result "<< std::endl;
return 0;
}