基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的协程库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_async_event_v2.cpp 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <chrono>
  2. #include <iostream>
  3. #include <string>
  4. #include <thread>
  5. #include "librf/librf.h"
  6. using namespace librf;
  7. using namespace std::chrono;
  8. //非协程的逻辑线程,或异步代码,可以通过event_t通知到协程,并且不会阻塞协程所在的线程。
  9. static std::thread async_set_event_all(const event_t & e, std::chrono::milliseconds dt)
  10. {
  11. return std::thread([=]
  12. {
  13. std::this_thread::sleep_for(dt);
  14. e.signal_all();
  15. });
  16. }
  17. static std::thread async_set_event_one(event_t e, std::chrono::milliseconds dt)
  18. {
  19. return std::thread([=]
  20. {
  21. std::this_thread::sleep_for(dt);
  22. e.signal();
  23. });
  24. }
  25. static future_t<> resumable_wait_event(event_t e, int idx)
  26. {
  27. auto result = co_await e;
  28. if (result)
  29. std::cout << "[" << idx << "]event signal!" << std::endl;
  30. else
  31. std::cout << "[" << idx << "]time out!" << std::endl;
  32. }
  33. static future_t<> resumable_wait_timeout(event_t e, milliseconds dt, int idx)
  34. {
  35. auto result = co_await e.wait_for(dt);
  36. if (result)
  37. std::cout << "[" << idx << "]event signal!" << std::endl;
  38. else
  39. std::cout << "[" << idx << "]time out!" << std::endl;
  40. }
  41. static void test_notify_all()
  42. {
  43. event_t evt;
  44. go resumable_wait_event(evt, 0);
  45. go resumable_wait_event(evt, 1);
  46. go resumable_wait_event(evt, 2);
  47. auto tt = async_set_event_all(evt, 100ms);
  48. this_scheduler()->run_until_notask();
  49. tt.join();
  50. }
  51. static void test_notify_one()
  52. {
  53. using namespace std::chrono;
  54. {
  55. event_t evt;
  56. go resumable_wait_event(evt, 10);
  57. go resumable_wait_event(evt, 11);
  58. go resumable_wait_event(evt, 12);
  59. auto tt1 = async_set_event_one(evt, 100ms);
  60. auto tt2 = async_set_event_one(evt, 500ms);
  61. auto tt3 = async_set_event_one(evt, 800ms);
  62. this_scheduler()->run_until_notask();
  63. tt1.join();
  64. tt2.join();
  65. tt3.join();
  66. }
  67. }
  68. static void test_wait_all_timeout()
  69. {
  70. using namespace std::chrono;
  71. srand((int)time(nullptr));
  72. event_t evts[10];
  73. std::vector<std::thread> vtt;
  74. for(size_t i = 0; i < std::size(evts); ++i)
  75. {
  76. go resumable_wait_timeout(evts[i], 100ms, (int)i);
  77. vtt.emplace_back(async_set_event_one(evts[i], 1ms * (50 + i * 10)));
  78. }
  79. this_scheduler()->run_until_notask();
  80. for (auto& tt : vtt)
  81. tt.join();
  82. }
  83. void resumable_main_event_v2()
  84. {
  85. test_notify_all();
  86. std::cout << std::endl;
  87. test_notify_one();
  88. std::cout << std::endl;
  89. test_wait_all_timeout();
  90. std::cout << std::endl;
  91. }
  92. #if LIBRF_TUTORIAL_STAND_ALONE
  93. int main()
  94. {
  95. resumable_main_event_v2();
  96. return 0;
  97. }
  98. #endif