基于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.cpp 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <chrono>
  2. #include <iostream>
  3. #include <string>
  4. #include <conio.h>
  5. #include <thread>
  6. #include "librf.h"
  7. using namespace resumef;
  8. //非协程的逻辑线程,或异步代码,可以通过event_t通知到协程,并且不会阻塞协程所在的线程。
  9. std::thread async_set_event(const event_t & e, std::chrono::milliseconds dt)
  10. {
  11. return std::thread([=]
  12. {
  13. std::this_thread::sleep_for(dt);
  14. e.signal();
  15. });
  16. }
  17. future_t<> resumable_wait_event(const event_t & e)
  18. {
  19. using namespace std::chrono;
  20. if (co_await e.wait() == false)
  21. std::cout << "time out!" << std::endl;
  22. else
  23. std::cout << "event signal!" << std::endl;
  24. }
  25. void test_wait_one()
  26. {
  27. using namespace std::chrono;
  28. {
  29. event_t evt;
  30. go resumable_wait_event(evt);
  31. auto tt = async_set_event(evt, 1000ms);
  32. this_scheduler()->run_until_notask();
  33. tt.join();
  34. }
  35. {
  36. event_t evt2(1);
  37. go[&]() -> future_t<>
  38. {
  39. (void)co_await evt2.wait();
  40. std::cout << "event signal on 1!" << std::endl;
  41. };
  42. go[&]() -> future_t<>
  43. {
  44. (void)co_await evt2.wait();
  45. std::cout << "event signal on 2!" << std::endl;
  46. };
  47. std::cout << std::this_thread::get_id() << std::endl;
  48. auto tt = async_set_event(evt2, 1000ms);
  49. this_scheduler()->run_until_notask();
  50. tt.join();
  51. }
  52. }
  53. void test_wait_any()
  54. {
  55. using namespace std::chrono;
  56. event_t evts[8];
  57. go[&]() -> future_t<>
  58. {
  59. for (size_t i = 0; i < _countof(evts); ++i)
  60. {
  61. intptr_t idx = co_await event_t::wait_any(evts);
  62. std::cout << "event " << idx << " signal!" << std::endl;
  63. }
  64. };
  65. std::vector<std::thread> vtt;
  66. srand((int)time(nullptr));
  67. for (auto & e : evts)
  68. {
  69. vtt.emplace_back(async_set_event(e, 1ms * (500 + rand() % 1000)));
  70. }
  71. this_scheduler()->run_until_notask();
  72. for (auto & tt : vtt)
  73. tt.join();
  74. }
  75. void test_wait_all()
  76. {
  77. using namespace std::chrono;
  78. event_t evts[8];
  79. go[&]() -> future_t<>
  80. {
  81. if (co_await event_t::wait_all(evts))
  82. std::cout << "all event signal!" << std::endl;
  83. else
  84. std::cout << "time out!" << std::endl;
  85. };
  86. std::vector<std::thread> vtt;
  87. srand((int)time(nullptr));
  88. for (auto & e : evts)
  89. {
  90. vtt.emplace_back(async_set_event(e, 1ms * (500 + rand() % 1000)));
  91. }
  92. this_scheduler()->run_until_notask();
  93. for (auto & tt : vtt)
  94. tt.join();
  95. }
  96. void test_wait_all_timeout()
  97. {
  98. using namespace std::chrono;
  99. event_t evts[8];
  100. go[&]() -> future_t<>
  101. {
  102. if (co_await event_t::wait_all_for(1000ms, evts))
  103. std::cout << "all event signal!" << std::endl;
  104. else
  105. std::cout << "time out!" << std::endl;
  106. };
  107. std::vector<std::thread> vtt;
  108. srand((int)time(nullptr));
  109. for (auto & e : evts)
  110. {
  111. vtt.emplace_back(async_set_event(e, 1ms * (500 + rand() % 1000)));
  112. }
  113. this_scheduler()->run_until_notask();
  114. for (auto & tt : vtt)
  115. tt.join();
  116. }
  117. void resumable_main_event()
  118. {
  119. test_wait_one();
  120. std::cout << std::endl;
  121. test_wait_any();
  122. std::cout << std::endl;
  123. test_wait_all();
  124. std::cout << std::endl;
  125. test_wait_all_timeout();
  126. std::cout << std::endl;
  127. }