基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的协程库
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

test_async_mutex.cpp 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <chrono>
  2. #include <iostream>
  3. #include <string>
  4. #include <conio.h>
  5. #include <thread>
  6. #include <deque>
  7. #include "librf.h"
  8. using namespace resumef;
  9. using namespace std::chrono;
  10. static mutex_t g_lock;
  11. static intptr_t g_counter = 0;
  12. static const size_t N = 10;
  13. //🔒-50ms-🔒🗝🗝-150ms-|
  14. //-------------.........
  15. static future_t<> test_mutex_pop(size_t idx)
  16. {
  17. for (size_t i = 0; i < N / 2; ++i)
  18. {
  19. {
  20. auto _locker = co_await g_lock.lock(); //_locker析构后,会调用对应的unlock()函数。
  21. --g_counter;
  22. std::cout << "pop :" << g_counter << " on " << idx << std::endl;
  23. co_await 50ms;
  24. auto _locker_2 = co_await g_lock.lock();
  25. --g_counter;
  26. std::cout << "pop :" << g_counter << " on " << idx << std::endl;
  27. }
  28. co_await 150ms;
  29. }
  30. }
  31. //🔒-50ms-🗝-50ms-🔒-50ms-🗝-50ms-|
  32. //---------........---------.......
  33. static future_t<> test_mutex_push(size_t idx)
  34. {
  35. for (size_t i = 0; i < N; ++i)
  36. {
  37. {
  38. auto _locker = co_await g_lock;
  39. ++g_counter;
  40. std::cout << "push:" << g_counter << " on " << idx << std::endl;
  41. co_await 50ms;
  42. }
  43. co_await 50ms;
  44. }
  45. }
  46. //🔒-50ms-🗝-50ms-🔒-50ms-🗝-50ms-|
  47. //---------........---------.......
  48. static std::thread test_mutex_async_push(size_t idx)
  49. {
  50. return std::thread([=]
  51. {
  52. char provide_unique_address = 0;
  53. for (size_t i = 0; i < N; ++i)
  54. {
  55. {
  56. auto _locker = g_lock.lock(&provide_unique_address);
  57. ++g_counter;
  58. std::cout << "push:" << g_counter << " on " << idx << std::endl;
  59. std::this_thread::sleep_for(50ms);
  60. }
  61. std::this_thread::sleep_for(50ms);
  62. }
  63. });
  64. }
  65. static void resumable_mutex_synch()
  66. {
  67. go test_mutex_push(0);
  68. go test_mutex_pop(1);
  69. this_scheduler()->run_until_notask();
  70. std::cout << "result:" << g_counter << std::endl;
  71. }
  72. static void resumable_mutex_async()
  73. {
  74. auto th = test_mutex_async_push(0);
  75. std::this_thread::sleep_for(25ms);
  76. go test_mutex_pop(1);
  77. this_scheduler()->run_until_notask();
  78. th.join();
  79. std::cout << "result:" << g_counter << std::endl;
  80. }
  81. void resumable_main_mutex()
  82. {
  83. resumable_mutex_synch();
  84. std::cout << std::endl;
  85. resumable_mutex_async();
  86. }