#include #include #include template class threadsafe_queue { private: std::mutex mut; std::queue data_queue; std::condition_variable data_cond; public: void push(T new_value) { std::lock_guard lk(mut); data_queue.push(new_value); data_cond.notify_one(); } void wait_and_pop(T& value) { std::unique_lock lk(mut); data_cond.wait(lk,[this]{return !data_queue.empty();}); value=data_queue.front(); data_queue.pop(); } }; struct data_chunk {}; data_chunk prepare_data(); bool more_data_to_prepare(); void process(data_chunk); bool is_last_chunk(data_chunk); threadsafe_queue data_queue; void data_preparation_thread() { while(more_data_to_prepare()) { data_chunk const data=prepare_data(); data_queue.push(data); } } void data_processing_thread() { while(true) { data_chunk data; data_queue.wait_and_pop(data); process(data); if(is_last_chunk(data)) break; } }