tennis.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright (C) 2001-2003
  2. // William E. Kempf
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #undef BOOST_THREAD_VERSION
  7. #define BOOST_THREAD_VERSION 2
  8. #include <boost/thread/mutex.hpp>
  9. #include <boost/thread/condition.hpp>
  10. #include <boost/thread/thread_only.hpp>
  11. #include <boost/thread/xtime.hpp>
  12. #include <iostream>
  13. #if defined(BOOST_HAS_WINTHREADS)
  14. # include <windows.h>
  15. # include <process.h>
  16. #endif
  17. enum game_state
  18. {
  19. START,
  20. PLAYER_A,
  21. PLAYER_B,
  22. GAME_OVER,
  23. ONE_PLAYER_GONE,
  24. BOTH_PLAYERS_GONE
  25. };
  26. int state;
  27. boost::mutex mutex;
  28. boost::condition cond;
  29. const char* player_name(int state)
  30. {
  31. if (state == PLAYER_A)
  32. return "PLAYER-A";
  33. if (state == PLAYER_B)
  34. return "PLAYER-B";
  35. throw "bad player";
  36. //return 0;
  37. }
  38. void player(int active)
  39. {
  40. boost::unique_lock<boost::mutex> lock(mutex);
  41. int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
  42. while (state < GAME_OVER)
  43. {
  44. //std::cout << player_name(active) << ": Play." << std::endl;
  45. state = other;
  46. cond.notify_all();
  47. do
  48. {
  49. cond.wait(lock);
  50. if (state == other)
  51. {
  52. std::cout << "---" << player_name(active)
  53. << ": Spurious wakeup!" << std::endl;
  54. }
  55. } while (state == other);
  56. }
  57. ++state;
  58. std::cout << player_name(active) << ": Gone." << std::endl;
  59. cond.notify_all();
  60. }
  61. struct thread_adapt
  62. {
  63. thread_adapt(void (*func)(void*), void* param)
  64. : _func(func), _param(param)
  65. {
  66. }
  67. int operator()() const
  68. {
  69. _func(_param);
  70. return 0;
  71. }
  72. void (*_func)(void*);
  73. void* _param;
  74. };
  75. class thread_adapter
  76. {
  77. public:
  78. thread_adapter(void (*func)(void*), void* param)
  79. : _func(func), _param(param)
  80. {
  81. }
  82. void operator()() const { _func(_param); }
  83. private:
  84. void (*_func)(void*);
  85. void* _param;
  86. };
  87. int main()
  88. {
  89. state = START;
  90. boost::thread thrda(&player, PLAYER_A);
  91. boost::thread thrdb(&player, PLAYER_B);
  92. boost::xtime xt;
  93. boost::xtime_get(&xt, boost::TIME_UTC_);
  94. xt.sec += 1;
  95. boost::thread::sleep(xt);
  96. {
  97. boost::unique_lock<boost::mutex> lock(mutex);
  98. std::cout << "---Noise ON..." << std::endl;
  99. }
  100. for (int i = 0; i < 10; ++i)
  101. cond.notify_all();
  102. {
  103. boost::unique_lock<boost::mutex> lock(mutex);
  104. std::cout << "---Noise OFF..." << std::endl;
  105. state = GAME_OVER;
  106. cond.notify_all();
  107. do
  108. {
  109. cond.wait(lock);
  110. } while (state != BOTH_PLAYERS_GONE);
  111. }
  112. std::cout << "GAME OVER" << std::endl;
  113. thrda.join();
  114. thrdb.join();
  115. return 0;
  116. }