#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; } }