fork(2) download
  1. #include <iostream>
  2. #include <thread>
  3. #include <chrono>
  4. #include <atomic>
  5. #include <functional>
  6. #include <mutex>
  7. #include <condition_variable>
  8.  
  9. using namespace std;
  10.  
  11. bool isMultiThreaded = true;
  12.  
  13. struct RenderThread
  14. {
  15. RenderThread()
  16. {
  17. end = false;
  18. readyToDraw = false;
  19. }
  20.  
  21. void Run()
  22. {
  23. while (!end)
  24. {
  25. DoJob();
  26. }
  27. }
  28.  
  29. void DoJob()
  30. {
  31. unique_lock<mutex> lk(renderReadyMutex);
  32. renderReady.wait(lk, [this](){ return readyToDraw; });
  33.  
  34. // RENDER DATA
  35. this_thread::sleep_for(chrono::milliseconds(15)); // simulated render time
  36. cout << "frame " << count << ": " << frame << endl;
  37. ++count;
  38.  
  39. readyToDraw = false;
  40.  
  41. lk.unlock();
  42. renderReady.notify_one();
  43. }
  44.  
  45. atomic<bool> end;
  46.  
  47. mutex renderReadyMutex;
  48. condition_variable renderReady;
  49. //mutex frame_mutex;
  50. int frame = -10;
  51. int count = 0;
  52.  
  53. bool readyToDraw;
  54. };
  55.  
  56. struct UpdateThread
  57. {
  58. UpdateThread(RenderThread& rt)
  59. : m_rt(rt)
  60. {}
  61.  
  62. void Run()
  63. {
  64. this_thread::sleep_for(chrono::milliseconds(500));
  65.  
  66. for (int i = 0; i < 20; ++i)
  67. {
  68. // DO GAME UPDATE
  69.  
  70. // when this is uncommented everything is fine
  71. // this_thread::sleep_for(chrono::milliseconds(10)); // simulated update time
  72.  
  73. // PREPARE RENDER THREAD
  74. unique_lock<mutex> lk(m_rt.renderReadyMutex);
  75. m_rt.renderReady.wait(lk, [this](){ return !m_rt.readyToDraw; });
  76.  
  77. m_rt.readyToDraw = true;
  78.  
  79. // SUPPLY RENDER THREAD WITH DATA TO RENDER
  80. m_rt.frame = i;
  81.  
  82. lk.unlock();
  83. m_rt.renderReady.notify_one();
  84.  
  85. if (!isMultiThreaded)
  86. m_rt.DoJob();
  87. }
  88.  
  89. m_rt.end = true;
  90. }
  91.  
  92. RenderThread& m_rt;
  93. };
  94.  
  95. int main()
  96. {
  97. auto start = chrono::high_resolution_clock::now();
  98.  
  99. RenderThread rt;
  100. UpdateThread u(rt);
  101.  
  102. thread* rendering = nullptr;
  103. if (isMultiThreaded)
  104. rendering = new thread(bind(&RenderThread::Run, &rt));
  105.  
  106. u.Run();
  107.  
  108. if (rendering)
  109. rendering->join();
  110.  
  111. auto duration = chrono::high_resolution_clock::now() - start;
  112. cout << "Duration: " << double(chrono::duration_cast<chrono::microseconds>(duration).count())/1000 << endl;
  113.  
  114.  
  115. return 0;
  116. }
Success #stdin #stdout 0s 11664KB
stdin
Standard input is empty
stdout
frame 0: 0
frame 1: 1
frame 2: 2
frame 3: 3
frame 4: 4
frame 5: 5
frame 6: 6
frame 7: 7
frame 8: 8
frame 9: 9
frame 10: 10
frame 11: 11
frame 12: 12
frame 13: 13
frame 14: 14
frame 15: 15
frame 16: 16
frame 17: 17
frame 18: 18
frame 19: 19
Duration: 802.106