#include <thread>
#include <condition_variable>
#include <memory>
#include <iostream>
#include <list>
#include <atomic>
std::condition_variable cv;
std::mutex m;
std::thread t;
std::atomic<bool> shouldExit;
std::list<int> jobs;

void thread_func()
{
  while (!shouldExit) 
  {
  	int j ;
  	{
      std::unique_lock<std::mutex> lock(m);
      while (jobs.empty() && !shouldExit) {
        cv.wait(lock);
      }
      // Do some stuff
      if (jobs.empty()) {
        continue;
      }
      // Get a job and do something with it
      j = std::move(jobs.front());
      jobs.pop_front();
  	}
    std::cout << "Do something with job " << j << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  }
}

int main()
{
  shouldExit.store(false);
  t = std::thread(thread_func);

  for (int i = 1; i < 100; ++i) {
    std::cout << "Push to job " << i << std::endl;
    {
    std::lock_guard<std::mutex> lock(m);
    jobs.push_back(i);
    cv.notify_one();
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  }

  // To wait for thread exit
  shouldExit.store(true);
  cv.notify_one();
  t.join();
  return 0;
}