ChihHao-Su

Untitled

Sep 9th, 2025 (edited)
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.69 KB | Source Code | 0 0
  1. /////////////////////////////////
  2. // 程序一:以协程包装阻塞的库中的功能
  3. /////////////////////////////////
  4.  
  5. using namespace std::chrono_literals;
  6. namespace coro = concurrencpp;
  7.  
  8. namespace MyAPI {
  9.  
  10.     class Api {
  11.     private:
  12.         coro::runtime& runtime;
  13.         std::shared_ptr<coro::executor> mainThreadExecutor;
  14.         std::shared_ptr<coro::thread_pool_executor> workerExecutor; // Thread pool executor
  15.  
  16.     public:
  17.         Api(coro::runtime &runtime,
  18.             std::shared_ptr<coro::executor> mainThreadExecutor
  19.         ) :
  20.             runtime{ runtime },
  21.             mainThreadExecutor{ std::move(mainThreadExecutor) },
  22.             workerExecutor{ runtime.thread_pool_executor() } { }
  23.  
  24.         // 调 HTTP 接口
  25.         coro::result<std::string> callHttpApi() {
  26.             // 1. 切换到后台线程池执行耗时操作
  27.             co_await coro::resume_on(workerExecutor);
  28.            
  29.             // 醒來,已處於 workerExecutor
  30.             std::this_thread::sleep_for(1s); // 模拟耗时网络请求
  31.  
  32.             // 2. 操作完成,切换回主线程
  33.             co_await coro::resume_on(mainThreadExecutor);
  34.  
  35.             // 醒來,已處於 mainThreadExecutor
  36.             co_return "asdf";
  37.         }
  38.     };
  39.  
  40. } // namespace MyAPI
  41.  
  42.  
  43. bool btnClicked() {
  44.     static int frame = 0;
  45.     frame++;
  46.     // 模擬第四幀按下按鈕
  47.     return frame == 4;
  48. }
  49.  
  50. void drawUi() {
  51.     std::println("draw ui");
  52.     std::this_thread::sleep_for(0.3s);
  53. }
  54.  
  55. int main() {
  56.     coro::runtime runtime;
  57.     auto mainThreadExecutor = runtime.make_manual_executor();
  58.  
  59.     // --- 实例化 MyAPI::Api ---
  60.     MyAPI::Api myApi{ runtime, mainThreadExecutor };
  61.  
  62.     while (true) {
  63.         if (btnClicked()) {
  64.             [&]() -> coro::result<void> {
  65.                 std::cout << "onBtn started on thread: " << std::this_thread::get_id() << std::endl;
  66.                 std::println("耗时任务执行始");
  67.  
  68.                 co_await myApi.callHttpApi();
  69.  
  70.                 std::cout << "onBtn resumed on thread: " << std::this_thread::get_id() << std::endl;
  71.                 std::println("耗时任务执行终");
  72.             }();
  73.         }
  74.  
  75.         mainThreadExecutor->loop_once();
  76.         drawUi();
  77.     }
  78.  
  79.     return 0;
  80. }
  81.  
  82. /*
  83. 程序一的输出如下:
  84. draw ui
  85. draw ui
  86. draw ui
  87. onBtn started on thread: 12628
  88. 耗时任务执行始
  89. draw ui
  90. draw ui
  91. draw ui
  92. draw ui
  93. onBtn resumed on thread: 12628
  94. 耗时任务执行终
  95. draw ui
  96. draw ui
  97. draw ui
  98. */
  99.  
  100. /////////////////////////////////
  101. // 程序二:Promise 的运用
  102. /////////////////////////////////
  103.  
  104. using namespace std::chrono_literals;
  105. namespace coro = concurrencpp;
  106.  
  107. namespace MyAPI {
  108.  
  109.     struct BackendMsg
  110.     {
  111.         std::string id;
  112.         std::string data;
  113.     };
  114.  
  115.     class Api {
  116.     public:
  117.         std::unordered_map<std::string, coro::result_promise<std::string>> reqId2Promise;
  118.  
  119.         // 当收到 websockets 消息时,调用此函数
  120.         void onRecvBackendMsg(BackendMsg msg) {
  121.             if (auto it = reqId2Promise.find(msg.id); it != reqId2Promise.end()) {
  122.                 it->second.set_result(msg.data);
  123.             }
  124.         }
  125.        
  126.         // websockets 发一个信息,并等待这个信息的回复
  127.         coro::result<std::string> sendReqAndWaitForResp(BackendMsg msg) {
  128.             std::println("已发送 ID 为 {} 的消息,正等待回应……", msg.id);
  129.             auto& promise = reqId2Promise[msg.id];
  130.             // sendMsgToBackend(msg);
  131.             std::string resp = co_await promise.get_result();
  132.             std::println("回应:{}", resp);
  133.             co_return resp;
  134.         }
  135.     };
  136.  
  137. } // namespace MyAPI
  138.  
  139.  
  140. bool btn1Clicked() {
  141.     static int frame = 0;
  142.     frame++;
  143.     // 模擬第四幀按下按鈕
  144.     return frame == 4;
  145. }
  146.  
  147. bool btn2Clicked() {
  148.     static int frame = 0;
  149.     frame++;
  150.     // 模擬第六幀按下按鈕
  151.     return frame == 6;
  152. }
  153.  
  154. void drawUi() {
  155.     std::println("draw ui");
  156.     std::this_thread::sleep_for(0.3s);
  157. }
  158.  
  159. int main() {
  160.     MyAPI::Api myApi;
  161.  
  162.     while (true) {
  163.         if (btn1Clicked()) {
  164.             [&]() -> coro::result<void> {
  165.                 std::string resp = co_await myApi.sendReqAndWaitForResp({ "test-msg-1", "PING!" });
  166.                 std::println("收到回应{}!", resp);
  167.             }();
  168.         }
  169.         if (btn2Clicked()) {
  170.             myApi.onRecvBackendMsg({ "test-msg-1", "PONG!" });
  171.         }
  172.  
  173.         drawUi();
  174.     }
  175.  
  176.     return 0;
  177. }
  178.  
  179. /*
  180. 程序二的输出如下:
  181. draw ui
  182. draw ui
  183. draw ui
  184. 已发送 ID 为 test-msg-1 的消息,正等待回应……
  185. draw ui
  186. draw ui
  187. 回应:PONG!
  188. 收到回应PONG!!
  189. draw ui
  190. draw ui
  191. draw ui
  192. ……
  193. */
Advertisement
Add Comment
Please, Sign In to add comment