[{"data":1,"prerenderedAt":6658},["ShallowReactive",2],{"wiki-page-/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io":3,"wiki-doc-items-/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io":6232,"language-switcher-data-/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io":6642,"wiki-i18n-paths-/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io":6657},{"id":4,"title":5,"body":6,"canonicalPath":6214,"chapter":6215,"chapterSort":6216,"date":6217,"description":60,"docI18nKey":6218,"docKey":6219,"docRoot":6220,"docTitle":6221,"extension":6222,"i18nKey":6223,"isBlogPost":6224,"isWikiDoc":97,"isWikiIndex":6224,"layout":6225,"legacyPath":6226,"locale":6227,"localeSlug":6228,"meta":6229,"navigation":97,"path":6214,"seo":6230,"sourcePath":6226,"sourceStem":6223,"stem":6223,"wikiDepth":67,"__hash__":6231},"content/wiki/2023-10-05-Cplusplus教学/ch19-1-1-定时器与异步IO.md","定时器与异步 IO",{"type":7,"value":8,"toc":6136},"minimark",[9,25,32,35,44,48,51,54,297,304,307,342,345,353,356,362,365,371,374,381,384,398,401,404,411,414,421,427,430,433,442,449,473,476,482,485,492,495,497,504,507,510,538,541,937,941,944,972,975,978,984,987,1001,1004,1010,1012,1018,1021,1029,1032,1044,1050,1056,1062,1065,1094,1097,1103,1109,1140,1143,1149,1152,1155,1159,1162,1167,1170,1176,1182,1184,1191,1194,1197,1222,1225,1735,1739,1742,1770,1773,1775,1781,1784,1790,1793,1799,1801,1807,1810,1813,1825,1828,1834,1840,1843,1880,1883,1889,1895,1900,1902,1909,1912,1915,1918,1924,1927,2459,2463,2466,2494,2497,2499,2505,2508,2514,2517,2523,2525,2531,2534,2544,2547,2553,2556,2559,2562,2581,2588,2591,2597,2600,2602,2606,2609,2612,2615,2621,2624,3071,3075,3078,3106,3109,3111,3117,3120,3126,3128,3134,3137,3140,3201,3204,3209,3218,3221,3223,3269,3272,3278,3285,3291,3297,3305,3308,3311,3335,3340,3346,3376,3382,3384,3388,3391,3394,3411,3414,4039,4043,4046,4074,4077,4079,4085,4087,4093,4096,4102,4104,4110,4113,4120,4123,4135,4138,4140,4146,4149,4155,4158,4164,4167,4823,4827,4830,4858,4861,4864,4870,4873,4879,4882,4885,4888,4894,4903,4912,4914,4957,4960,4981,4984,4986,4994,4997,5010,5015,5021,5024,5901,5905,5908,5936,5939,5944,5950,5953,5959,5966,5969,5979,5982,5988,5991,5997,6002,6004,6024,6030,6033,6035,6038,6041,6080,6132],[10,11,12],"blockquote",{},[13,14,15,16,19,20,24],"p",{},"本节是整套 Boost.Asio 教程最重要的一节。",[17,18],"br",{},"\n串口、TCP、UDP 的异步模型都和定时器类似：先注册异步操作，然后由 ",[21,22,23],"code",{},"io_context.run()"," 驱动回调执行。",[13,26,27,28,31],{},"本节所有异步回调都使用 ",[21,29,30],{},"std::bind","，暂时不使用 lambda。",[33,34],"hr",{},[36,37,39,40,43],"h2",{"id":38},"示例-1普通-main-里写同步定时器","示例 1：普通 ",[21,41,42],{},"main()"," 里写同步定时器",[45,46,47],"h3",{"id":47},"程序目标",[13,49,50],{},"先写最简单的阻塞式定时器：程序启动后立刻打印一句话，然后阻塞等待 2 秒，再打印结束。",[45,52,53],{"id":53},"完整代码",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-cpp shiki shiki-themes github-light github-dark","#include \u003Cboost/asio.hpp>\n#include \u003Cchrono>\n#include \u003Ciostream>\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer(io, std::chrono::seconds(2));\n\n    std::cout \u003C\u003C \"程序开始：准备等待 2 秒\" \u003C\u003C std::endl;\n\n    // 同步等待会阻塞当前线程，时间没到之前不会继续往下执行。\n    timer.wait();\n\n    std::cout \u003C\u003C \"2 秒到了：timer.wait() 返回\" \u003C\u003C std::endl;\n\n    return 0;\n}\n","cpp","",[21,62,63,76,84,92,99,113,119,126,132,147,152,158,199,204,228,233,239,251,256,274,279,291],{"__ignoreMap":60},[64,65,68,72],"span",{"class":66,"line":67},"line",1,[64,69,71],{"class":70},"szBVR","#include",[64,73,75],{"class":74},"sZZnC"," \u003Cboost/asio.hpp>\n",[64,77,79,81],{"class":66,"line":78},2,[64,80,71],{"class":70},[64,82,83],{"class":74}," \u003Cchrono>\n",[64,85,87,89],{"class":66,"line":86},3,[64,88,71],{"class":70},[64,90,91],{"class":74}," \u003Ciostream>\n",[64,93,95],{"class":66,"line":94},4,[64,96,98],{"emptyLinePlaceholder":97},true,"\n",[64,100,102,105,109],{"class":66,"line":101},5,[64,103,104],{"class":70},"int",[64,106,108],{"class":107},"sScJk"," main",[64,110,112],{"class":111},"sVt8B","()\n",[64,114,116],{"class":66,"line":115},6,[64,117,118],{"class":111},"{\n",[64,120,122],{"class":66,"line":121},7,[64,123,125],{"class":124},"sJ8bj","    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n",[64,127,129],{"class":66,"line":128},8,[64,130,131],{"class":124},"    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n",[64,133,135,138,141,144],{"class":66,"line":134},9,[64,136,137],{"class":107},"    boost",[64,139,140],{"class":111},"::",[64,142,143],{"class":107},"asio",[64,145,146],{"class":111},"::io_context io;\n",[64,148,150],{"class":66,"line":149},10,[64,151,98],{"emptyLinePlaceholder":97},[64,153,155],{"class":66,"line":154},11,[64,156,157],{"class":124},"    // 创建定时器，并设置到期时间。\n",[64,159,161,163,165,167,170,173,176,179,181,184,186,189,192,196],{"class":66,"line":160},12,[64,162,137],{"class":107},[64,164,140],{"class":111},[64,166,143],{"class":107},[64,168,169],{"class":111},"::steady_timer ",[64,171,172],{"class":107},"timer",[64,174,175],{"class":111},"(io, ",[64,177,178],{"class":107},"std",[64,180,140],{"class":111},[64,182,183],{"class":107},"chrono",[64,185,140],{"class":111},[64,187,188],{"class":107},"seconds",[64,190,191],{"class":111},"(",[64,193,195],{"class":194},"sj4cs","2",[64,197,198],{"class":111},"));\n",[64,200,202],{"class":66,"line":201},13,[64,203,98],{"emptyLinePlaceholder":97},[64,205,207,210,213,216,219,222,225],{"class":66,"line":206},14,[64,208,209],{"class":107},"    std",[64,211,212],{"class":111},"::cout ",[64,214,215],{"class":70},"\u003C\u003C",[64,217,218],{"class":74}," \"程序开始：准备等待 2 秒\"",[64,220,221],{"class":70}," \u003C\u003C",[64,223,224],{"class":107}," std",[64,226,227],{"class":111},"::endl;\n",[64,229,231],{"class":66,"line":230},15,[64,232,98],{"emptyLinePlaceholder":97},[64,234,236],{"class":66,"line":235},16,[64,237,238],{"class":124},"    // 同步等待会阻塞当前线程，时间没到之前不会继续往下执行。\n",[64,240,242,245,248],{"class":66,"line":241},17,[64,243,244],{"class":111},"    timer.",[64,246,247],{"class":107},"wait",[64,249,250],{"class":111},"();\n",[64,252,254],{"class":66,"line":253},18,[64,255,98],{"emptyLinePlaceholder":97},[64,257,259,261,263,265,268,270,272],{"class":66,"line":258},19,[64,260,209],{"class":107},[64,262,212],{"class":111},[64,264,215],{"class":70},[64,266,267],{"class":74}," \"2 秒到了：timer.wait() 返回\"",[64,269,221],{"class":70},[64,271,224],{"class":107},[64,273,227],{"class":111},[64,275,277],{"class":66,"line":276},20,[64,278,98],{"emptyLinePlaceholder":97},[64,280,282,285,288],{"class":66,"line":281},21,[64,283,284],{"class":70},"    return",[64,286,287],{"class":194}," 0",[64,289,290],{"class":111},";\n",[64,292,294],{"class":66,"line":293},22,[64,295,296],{"class":111},"}\n",[13,298,299,303],{},[300,301,302],"strong",{},"运行结果","：见下方“运行输出与时间顺序”；如果示例涉及定时器、线程、网络或外部设备，具体时间和顺序可能会随环境略有变化。",[45,305,306],{"id":306},"编译运行",[55,308,312],{"className":309,"code":310,"language":311,"meta":60,"style":60},"language-bash shiki shiki-themes github-light github-dark","g++ demo1_sync_timer.cpp -o demo1_sync_timer -std=c++17 -lboost_system -pthread\n./demo1_sync_timer\n","bash",[21,313,314,337],{"__ignoreMap":60},[64,315,316,319,322,325,328,331,334],{"class":66,"line":67},[64,317,318],{"class":107},"g++",[64,320,321],{"class":74}," demo1_sync_timer.cpp",[64,323,324],{"class":194}," -o",[64,326,327],{"class":74}," demo1_sync_timer",[64,329,330],{"class":194}," -std=c++17",[64,332,333],{"class":194}," -lboost_system",[64,335,336],{"class":194}," -pthread\n",[64,338,339],{"class":66,"line":78},[64,340,341],{"class":107},"./demo1_sync_timer\n",[45,343,344],{"id":344},"运行输出与时间顺序",[55,346,351],{"className":347,"code":349,"language":350,"meta":60},[348],"language-text","程序开始：准备等待 2 秒\n","text",[21,352,349],{"__ignoreMap":60},[13,354,355],{},"等待约 2 秒后：",[55,357,360],{"className":358,"code":359,"language":350,"meta":60},[348],"2 秒到了：timer.wait() 返回\n",[21,361,359],{"__ignoreMap":60},[13,363,364],{},"完整输出类似：",[55,366,369],{"className":367,"code":368,"language":350,"meta":60},[348],"程序开始：准备等待 2 秒\n2 秒到了：timer.wait() 返回\n",[21,370,368],{"__ignoreMap":60},[45,372,373],{"id":373},"本示例需要注意的点",[13,375,376,377,380],{},"这个程序没有体现“异步”，因为 ",[21,378,379],{},"timer.wait()"," 会直接阻塞当前线程。",[13,382,383],{},"也就是说，程序卡在这里：",[55,385,387],{"className":57,"code":386,"language":59,"meta":60,"style":60},"timer.wait();\n",[21,388,389],{"__ignoreMap":60},[64,390,391,394,396],{"class":66,"line":67},[64,392,393],{"class":111},"timer.",[64,395,247],{"class":107},[64,397,250],{"class":111},[13,399,400],{},"2 秒没有到之前，下一行不会执行。",[45,402,403],{"id":403},"关键函数说明",[405,406,408],"h4",{"id":407},"boostasioio_context-io",[21,409,410],{},"boost::asio::io_context io;",[13,412,413],{},"作用：创建一个 Asio 事件循环对象。",[13,415,416,417,420],{},"在同步 ",[21,418,419],{},"wait()"," 示例中，它看起来没什么存在感；但到了异步版本，所有异步事件都要靠它驱动。",[405,422,424],{"id":423},"boostasiosteady_timer-timerio-stdchronoseconds2",[21,425,426],{},"boost::asio::steady_timer timer(io, std::chrono::seconds(2));",[13,428,429],{},"作用：创建一个基于稳定时钟的定时器，设置 2 秒后到期。",[13,431,432],{},"参数：",[55,434,436],{"className":57,"code":435,"language":59,"meta":60,"style":60},"io\n",[21,437,438],{"__ignoreMap":60},[64,439,440],{"class":66,"line":67},[64,441,435],{"class":111},[13,443,444,445,448],{},"表示这个 timer 归哪个 ",[21,446,447],{},"io_context"," 管。",[55,450,452],{"className":57,"code":451,"language":59,"meta":60,"style":60},"std::chrono::seconds(2)\n",[21,453,454],{"__ignoreMap":60},[64,455,456,458,460,462,464,466,468,470],{"class":66,"line":67},[64,457,178],{"class":107},[64,459,140],{"class":111},[64,461,183],{"class":107},[64,463,140],{"class":111},[64,465,188],{"class":107},[64,467,191],{"class":111},[64,469,195],{"class":194},[64,471,472],{"class":111},")\n",[13,474,475],{},"表示相对当前时间 2 秒后到期。",[405,477,479],{"id":478},"timerwait",[21,480,481],{},"timer.wait();",[13,483,484],{},"作用：阻塞等待 timer 到期。",[13,486,487,488,491],{},"返回值：",[21,489,490],{},"void","。",[13,493,494],{},"特点：简单，但是会阻塞当前线程。机器人程序里如果在主控制循环里这么写，很容易卡住整个程序。",[33,496],{},[36,498,500,501,503],{"id":499},"示例-2普通-main-里写异步定时器","示例 2：普通 ",[21,502,42],{}," 里写异步定时器",[45,505,47],{"id":506},"程序目标-1",[13,508,509],{},"把示例 1 改成异步写法：",[511,512,513,517,523,529,532],"ol",{},[514,515,516],"li",{},"注册一个 2 秒定时器；",[514,518,519,522],{},[21,520,521],{},"async_wait()"," 不阻塞；",[514,524,525,528],{},[21,526,527],{},"io.run()"," 开始阻塞；",[514,530,531],{},"2 秒后回调函数被执行；",[514,533,534,535,537],{},"没有任务后 ",[21,536,527],{}," 返回。",[45,539,53],{"id":540},"完整代码-1",[55,542,544],{"className":57,"code":543,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n\nvoid on_timer(const boost::system::error_code& ec)\n{\n    if (ec)\n    {\n        std::cout \u003C\u003C \"定时器被取消，错误信息：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return;\n    }\n\n    std::cout \u003C\u003C \"回调函数 on_timer：2 秒到了\" \u003C\u003C std::endl;\n}\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer(io, std::chrono::seconds(2));\n\n    std::cout \u003C\u003C \"main：注册 async_wait\" \u003C\u003C std::endl;\n\n    // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n    timer.async_wait(std::bind(on_timer, std::placeholders::_1));\n\n    std::cout \u003C\u003C \"main：async_wait 已经返回，但回调还没执行\" \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"main：准备调用 io.run()\" \u003C\u003C std::endl;\n\n    io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回，程序结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,545,546,552,559,565,572,578,582,616,620,628,633,662,669,674,678,695,699,703,711,715,719,723,733,738,743,774,779,797,802,808,838,843,861,879,884,895,900,918,923,932],{"__ignoreMap":60},[64,547,548,550],{"class":66,"line":67},[64,549,71],{"class":70},[64,551,75],{"class":74},[64,553,554,556],{"class":66,"line":78},[64,555,71],{"class":70},[64,557,558],{"class":74}," \u003Cboost/system/error_code.hpp>\n",[64,560,561,563],{"class":66,"line":86},[64,562,71],{"class":70},[64,564,83],{"class":74},[64,566,567,569],{"class":66,"line":94},[64,568,71],{"class":70},[64,570,571],{"class":74}," \u003Cfunctional>\n",[64,573,574,576],{"class":66,"line":101},[64,575,71],{"class":70},[64,577,91],{"class":74},[64,579,580],{"class":66,"line":115},[64,581,98],{"emptyLinePlaceholder":97},[64,583,584,586,589,591,594,597,599,602,604,607,610,614],{"class":66,"line":121},[64,585,490],{"class":70},[64,587,588],{"class":107}," on_timer",[64,590,191],{"class":111},[64,592,593],{"class":70},"const",[64,595,596],{"class":107}," boost",[64,598,140],{"class":111},[64,600,601],{"class":107},"system",[64,603,140],{"class":111},[64,605,606],{"class":107},"error_code",[64,608,609],{"class":70},"&",[64,611,613],{"class":612},"s4XuR"," ec",[64,615,472],{"class":111},[64,617,618],{"class":66,"line":128},[64,619,118],{"class":111},[64,621,622,625],{"class":66,"line":134},[64,623,624],{"class":70},"    if",[64,626,627],{"class":111}," (ec)\n",[64,629,630],{"class":66,"line":149},[64,631,632],{"class":111},"    {\n",[64,634,635,638,640,642,645,647,650,653,656,658,660],{"class":66,"line":154},[64,636,637],{"class":107},"        std",[64,639,212],{"class":111},[64,641,215],{"class":70},[64,643,644],{"class":74}," \"定时器被取消，错误信息：\"",[64,646,221],{"class":70},[64,648,649],{"class":111}," ec.",[64,651,652],{"class":107},"message",[64,654,655],{"class":111},"() ",[64,657,215],{"class":70},[64,659,224],{"class":107},[64,661,227],{"class":111},[64,663,664,667],{"class":66,"line":160},[64,665,666],{"class":70},"        return",[64,668,290],{"class":111},[64,670,671],{"class":66,"line":201},[64,672,673],{"class":111},"    }\n",[64,675,676],{"class":66,"line":206},[64,677,98],{"emptyLinePlaceholder":97},[64,679,680,682,684,686,689,691,693],{"class":66,"line":230},[64,681,209],{"class":107},[64,683,212],{"class":111},[64,685,215],{"class":70},[64,687,688],{"class":74}," \"回调函数 on_timer：2 秒到了\"",[64,690,221],{"class":70},[64,692,224],{"class":107},[64,694,227],{"class":111},[64,696,697],{"class":66,"line":235},[64,698,296],{"class":111},[64,700,701],{"class":66,"line":241},[64,702,98],{"emptyLinePlaceholder":97},[64,704,705,707,709],{"class":66,"line":253},[64,706,104],{"class":70},[64,708,108],{"class":107},[64,710,112],{"class":111},[64,712,713],{"class":66,"line":258},[64,714,118],{"class":111},[64,716,717],{"class":66,"line":276},[64,718,125],{"class":124},[64,720,721],{"class":66,"line":281},[64,722,131],{"class":124},[64,724,725,727,729,731],{"class":66,"line":293},[64,726,137],{"class":107},[64,728,140],{"class":111},[64,730,143],{"class":107},[64,732,146],{"class":111},[64,734,736],{"class":66,"line":735},23,[64,737,98],{"emptyLinePlaceholder":97},[64,739,741],{"class":66,"line":740},24,[64,742,157],{"class":124},[64,744,746,748,750,752,754,756,758,760,762,764,766,768,770,772],{"class":66,"line":745},25,[64,747,137],{"class":107},[64,749,140],{"class":111},[64,751,143],{"class":107},[64,753,169],{"class":111},[64,755,172],{"class":107},[64,757,175],{"class":111},[64,759,178],{"class":107},[64,761,140],{"class":111},[64,763,183],{"class":107},[64,765,140],{"class":111},[64,767,188],{"class":107},[64,769,191],{"class":111},[64,771,195],{"class":194},[64,773,198],{"class":111},[64,775,777],{"class":66,"line":776},26,[64,778,98],{"emptyLinePlaceholder":97},[64,780,782,784,786,788,791,793,795],{"class":66,"line":781},27,[64,783,209],{"class":107},[64,785,212],{"class":111},[64,787,215],{"class":70},[64,789,790],{"class":74}," \"main：注册 async_wait\"",[64,792,221],{"class":70},[64,794,224],{"class":107},[64,796,227],{"class":111},[64,798,800],{"class":66,"line":799},28,[64,801,98],{"emptyLinePlaceholder":97},[64,803,805],{"class":66,"line":804},29,[64,806,807],{"class":124},"    // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n",[64,809,811,813,816,818,820,822,825,828,830,832,835],{"class":66,"line":810},30,[64,812,244],{"class":111},[64,814,815],{"class":107},"async_wait",[64,817,191],{"class":111},[64,819,178],{"class":107},[64,821,140],{"class":111},[64,823,824],{"class":107},"bind",[64,826,827],{"class":111},"(on_timer, ",[64,829,178],{"class":107},[64,831,140],{"class":111},[64,833,834],{"class":107},"placeholders",[64,836,837],{"class":111},"::_1));\n",[64,839,841],{"class":66,"line":840},31,[64,842,98],{"emptyLinePlaceholder":97},[64,844,846,848,850,852,855,857,859],{"class":66,"line":845},32,[64,847,209],{"class":107},[64,849,212],{"class":111},[64,851,215],{"class":70},[64,853,854],{"class":74}," \"main：async_wait 已经返回，但回调还没执行\"",[64,856,221],{"class":70},[64,858,224],{"class":107},[64,860,227],{"class":111},[64,862,864,866,868,870,873,875,877],{"class":66,"line":863},33,[64,865,209],{"class":107},[64,867,212],{"class":111},[64,869,215],{"class":70},[64,871,872],{"class":74}," \"main：准备调用 io.run()\"",[64,874,221],{"class":70},[64,876,224],{"class":107},[64,878,227],{"class":111},[64,880,882],{"class":66,"line":881},34,[64,883,98],{"emptyLinePlaceholder":97},[64,885,887,890,893],{"class":66,"line":886},35,[64,888,889],{"class":111},"    io.",[64,891,892],{"class":107},"run",[64,894,250],{"class":111},[64,896,898],{"class":66,"line":897},36,[64,899,98],{"emptyLinePlaceholder":97},[64,901,903,905,907,909,912,914,916],{"class":66,"line":902},37,[64,904,209],{"class":107},[64,906,212],{"class":111},[64,908,215],{"class":70},[64,910,911],{"class":74}," \"main：io.run() 返回，程序结束\"",[64,913,221],{"class":70},[64,915,224],{"class":107},[64,917,227],{"class":111},[64,919,921],{"class":66,"line":920},38,[64,922,98],{"emptyLinePlaceholder":97},[64,924,926,928,930],{"class":66,"line":925},39,[64,927,284],{"class":70},[64,929,287],{"class":194},[64,931,290],{"class":111},[64,933,935],{"class":66,"line":934},40,[64,936,296],{"class":111},[13,938,939,303],{},[300,940,302],{},[45,942,306],{"id":943},"编译运行-1",[55,945,947],{"className":309,"code":946,"language":311,"meta":60,"style":60},"g++ demo2_async_timer.cpp -o demo2_async_timer -std=c++17 -lboost_system -pthread\n./demo2_async_timer\n",[21,948,949,967],{"__ignoreMap":60},[64,950,951,953,956,958,961,963,965],{"class":66,"line":67},[64,952,318],{"class":107},[64,954,955],{"class":74}," demo2_async_timer.cpp",[64,957,324],{"class":194},[64,959,960],{"class":74}," demo2_async_timer",[64,962,330],{"class":194},[64,964,333],{"class":194},[64,966,336],{"class":194},[64,968,969],{"class":66,"line":78},[64,970,971],{"class":107},"./demo2_async_timer\n",[45,973,344],{"id":974},"运行输出与时间顺序-1",[13,976,977],{},"程序立刻输出：",[55,979,982],{"className":980,"code":981,"language":350,"meta":60},[348],"main：注册 async_wait\nmain：async_wait 已经返回，但回调还没执行\nmain：准备调用 io.run()\n",[21,983,981],{"__ignoreMap":60},[13,985,986],{},"然后程序会卡在：",[55,988,990],{"className":57,"code":989,"language":59,"meta":60,"style":60},"io.run();\n",[21,991,992],{"__ignoreMap":60},[64,993,994,997,999],{"class":66,"line":67},[64,995,996],{"class":111},"io.",[64,998,892],{"class":107},[64,1000,250],{"class":111},[13,1002,1003],{},"等待约 2 秒后输出：",[55,1005,1008],{"className":1006,"code":1007,"language":350,"meta":60},[348],"回调函数 on_timer：2 秒到了\nmain：io.run() 返回，程序结束\n",[21,1009,1007],{"__ignoreMap":60},[13,1011,364],{},[55,1013,1016],{"className":1014,"code":1015,"language":350,"meta":60},[348],"main：注册 async_wait\nmain：async_wait 已经返回，但回调还没执行\nmain：准备调用 io.run()\n回调函数 on_timer：2 秒到了\nmain：io.run() 返回，程序结束\n",[21,1017,1015],{"__ignoreMap":60},[45,1019,373],{"id":1020},"本示例需要注意的点-1",[13,1022,1023,1025,1026,1028],{},[21,1024,521],{}," 不会等待 2 秒。它只是把“2 秒后执行回调”这件事注册到 ",[21,1027,447],{}," 里。",[13,1030,1031],{},"真正等待的是：",[55,1033,1034],{"className":57,"code":989,"language":59,"meta":60,"style":60},[21,1035,1036],{"__ignoreMap":60},[64,1037,1038,1040,1042],{"class":66,"line":67},[64,1039,996],{"class":111},[64,1041,892],{"class":107},[64,1043,250],{"class":111},[13,1045,1046,1047,1049],{},"所以不要把 ",[21,1048,521],{}," 理解成“异步版本的 wait”。更准确地说：",[55,1051,1054],{"className":1052,"code":1053,"language":350,"meta":60},[348],"async_wait() = 注册任务\nio.run() = 执行事件循环\non_timer() = 任务完成后的回调\n",[21,1055,1053],{"__ignoreMap":60},[45,1057,1059,1061],{"id":1058},"stdbind-说明",[21,1060,30],{}," 说明",[13,1063,1064],{},"这句代码：",[55,1066,1068],{"className":57,"code":1067,"language":59,"meta":60,"style":60},"timer.async_wait(std::bind(on_timer, std::placeholders::_1));\n",[21,1069,1070],{"__ignoreMap":60},[64,1071,1072,1074,1076,1078,1080,1082,1084,1086,1088,1090,1092],{"class":66,"line":67},[64,1073,393],{"class":111},[64,1075,815],{"class":107},[64,1077,191],{"class":111},[64,1079,178],{"class":107},[64,1081,140],{"class":111},[64,1083,824],{"class":107},[64,1085,827],{"class":111},[64,1087,178],{"class":107},[64,1089,140],{"class":111},[64,1091,834],{"class":107},[64,1093,837],{"class":111},[13,1095,1096],{},"意思是：",[55,1098,1101],{"className":1099,"code":1100,"language":350,"meta":60},[348],"当 timer 到期后，Boost.Asio 会传入一个 error_code。\n这个 error_code 会填到 std::placeholders::_1 的位置。\n最后调用 on_timer(ec)。\n",[21,1102,1100],{"__ignoreMap":60},[13,1104,1105,1108],{},[21,1106,1107],{},"on_timer"," 的函数签名必须能接收这个参数：",[55,1110,1112],{"className":57,"code":1111,"language":59,"meta":60,"style":60},"void on_timer(const boost::system::error_code& ec)\n",[21,1113,1114],{"__ignoreMap":60},[64,1115,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138],{"class":66,"line":67},[64,1117,490],{"class":70},[64,1119,588],{"class":107},[64,1121,191],{"class":111},[64,1123,593],{"class":70},[64,1125,596],{"class":107},[64,1127,140],{"class":111},[64,1129,601],{"class":107},[64,1131,140],{"class":111},[64,1133,606],{"class":107},[64,1135,609],{"class":70},[64,1137,613],{"class":612},[64,1139,472],{"class":111},[45,1141,403],{"id":1142},"关键函数说明-1",[405,1144,1146],{"id":1145},"timerasync_waithandler",[21,1147,1148],{},"timer.async_wait(handler)",[13,1150,1151],{},"作用：注册一个异步等待操作。",[13,1153,1154],{},"参数：一个回调函数对象。",[13,1156,487,1157,491],{},[21,1158,490],{},[13,1160,1161],{},"注意：它不会阻塞等待定时器到期。",[405,1163,1165],{"id":1164},"iorun",[21,1166,527],{},[13,1168,1169],{},"作用：启动事件循环，处理异步任务和回调函数。",[13,1171,1172,1173,491],{},"返回值：执行过的 handler 数量，类型通常可以看成 ",[21,1174,1175],{},"std::size_t",[13,1177,1178,1179,1181],{},"本例中，",[21,1180,527],{}," 执行了 1 个回调，所以返回值是 1。只是我们没有打印返回值。",[33,1183],{},[36,1185,1187,1188,1190],{"id":1186},"示例-3普通-main-里写两个异步定时器","示例 3：普通 ",[21,1189,42],{}," 里写两个异步定时器",[45,1192,47],{"id":1193},"程序目标-2",[13,1195,1196],{},"一个 timer 很难看出异步调度的感觉，所以这次写两个 timer：",[511,1198,1199,1205,1211,1217],{},[514,1200,1201,1204],{},[21,1202,1203],{},"timer1"," 1 秒后到期；",[514,1206,1207,1210],{},[21,1208,1209],{},"timer2"," 3 秒后到期；",[514,1212,1213,1214,1216],{},"两个 timer 都在同一个 ",[21,1215,447],{}," 里；",[514,1218,1219,1221],{},[21,1220,527],{}," 会等两个任务都完成后才返回。",[45,1223,53],{"id":1224},"完整代码-2",[55,1226,1228],{"className":57,"code":1227,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cstring>\n\nvoid on_timer(const boost::system::error_code& ec, const std::string& name)\n{\n    if (ec)\n    {\n        std::cout \u003C\u003C name \u003C\u003C \" 被取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return;\n    }\n\n    std::cout \u003C\u003C name \u003C\u003C \" 到期，执行回调\" \u003C\u003C std::endl;\n}\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer1(io, std::chrono::seconds(1));\n    boost::asio::steady_timer timer2(io, std::chrono::seconds(3));\n\n    std::cout \u003C\u003C \"main：注册 timer1，1 秒后到期\" \u003C\u003C std::endl;\n    // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n    timer1.async_wait(std::bind(on_timer,\n                                std::placeholders::_1,\n                                std::string(\"timer1\")));\n\n    std::cout \u003C\u003C \"main：注册 timer2，3 秒后到期\" \u003C\u003C std::endl;\n    timer2.async_wait(std::bind(on_timer,\n                                std::placeholders::_1,\n                                std::string(\"timer2\")));\n\n    std::cout \u003C\u003C \"main：调用 io.run()\" \u003C\u003C std::endl;\n\n    std::size_t count = io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回，一共执行了 \" \u003C\u003C count \u003C\u003C \" 个回调\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,1229,1230,1236,1242,1248,1254,1260,1267,1271,1314,1318,1324,1328,1358,1364,1368,1372,1393,1397,1401,1409,1413,1417,1421,1431,1435,1439,1470,1501,1505,1522,1526,1544,1556,1572,1576,1593,1610,1620,1635,1639,1656,1661,1684,1689,1716,1721,1730],{"__ignoreMap":60},[64,1231,1232,1234],{"class":66,"line":67},[64,1233,71],{"class":70},[64,1235,75],{"class":74},[64,1237,1238,1240],{"class":66,"line":78},[64,1239,71],{"class":70},[64,1241,558],{"class":74},[64,1243,1244,1246],{"class":66,"line":86},[64,1245,71],{"class":70},[64,1247,83],{"class":74},[64,1249,1250,1252],{"class":66,"line":94},[64,1251,71],{"class":70},[64,1253,571],{"class":74},[64,1255,1256,1258],{"class":66,"line":101},[64,1257,71],{"class":70},[64,1259,91],{"class":74},[64,1261,1262,1264],{"class":66,"line":115},[64,1263,71],{"class":70},[64,1265,1266],{"class":74}," \u003Cstring>\n",[64,1268,1269],{"class":66,"line":121},[64,1270,98],{"emptyLinePlaceholder":97},[64,1272,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1298,1300,1302,1304,1307,1309,1312],{"class":66,"line":128},[64,1274,490],{"class":70},[64,1276,588],{"class":107},[64,1278,191],{"class":111},[64,1280,593],{"class":70},[64,1282,596],{"class":107},[64,1284,140],{"class":111},[64,1286,601],{"class":107},[64,1288,140],{"class":111},[64,1290,606],{"class":107},[64,1292,609],{"class":70},[64,1294,613],{"class":612},[64,1296,1297],{"class":111},", ",[64,1299,593],{"class":70},[64,1301,224],{"class":107},[64,1303,140],{"class":111},[64,1305,1306],{"class":107},"string",[64,1308,609],{"class":70},[64,1310,1311],{"class":612}," name",[64,1313,472],{"class":111},[64,1315,1316],{"class":66,"line":134},[64,1317,118],{"class":111},[64,1319,1320,1322],{"class":66,"line":149},[64,1321,624],{"class":70},[64,1323,627],{"class":111},[64,1325,1326],{"class":66,"line":154},[64,1327,632],{"class":111},[64,1329,1330,1332,1334,1336,1339,1341,1344,1346,1348,1350,1352,1354,1356],{"class":66,"line":160},[64,1331,637],{"class":107},[64,1333,212],{"class":111},[64,1335,215],{"class":70},[64,1337,1338],{"class":111}," name ",[64,1340,215],{"class":70},[64,1342,1343],{"class":74}," \" 被取消：\"",[64,1345,221],{"class":70},[64,1347,649],{"class":111},[64,1349,652],{"class":107},[64,1351,655],{"class":111},[64,1353,215],{"class":70},[64,1355,224],{"class":107},[64,1357,227],{"class":111},[64,1359,1360,1362],{"class":66,"line":201},[64,1361,666],{"class":70},[64,1363,290],{"class":111},[64,1365,1366],{"class":66,"line":206},[64,1367,673],{"class":111},[64,1369,1370],{"class":66,"line":230},[64,1371,98],{"emptyLinePlaceholder":97},[64,1373,1374,1376,1378,1380,1382,1384,1387,1389,1391],{"class":66,"line":235},[64,1375,209],{"class":107},[64,1377,212],{"class":111},[64,1379,215],{"class":70},[64,1381,1338],{"class":111},[64,1383,215],{"class":70},[64,1385,1386],{"class":74}," \" 到期，执行回调\"",[64,1388,221],{"class":70},[64,1390,224],{"class":107},[64,1392,227],{"class":111},[64,1394,1395],{"class":66,"line":241},[64,1396,296],{"class":111},[64,1398,1399],{"class":66,"line":253},[64,1400,98],{"emptyLinePlaceholder":97},[64,1402,1403,1405,1407],{"class":66,"line":258},[64,1404,104],{"class":70},[64,1406,108],{"class":107},[64,1408,112],{"class":111},[64,1410,1411],{"class":66,"line":276},[64,1412,118],{"class":111},[64,1414,1415],{"class":66,"line":281},[64,1416,125],{"class":124},[64,1418,1419],{"class":66,"line":293},[64,1420,131],{"class":124},[64,1422,1423,1425,1427,1429],{"class":66,"line":735},[64,1424,137],{"class":107},[64,1426,140],{"class":111},[64,1428,143],{"class":107},[64,1430,146],{"class":111},[64,1432,1433],{"class":66,"line":740},[64,1434,98],{"emptyLinePlaceholder":97},[64,1436,1437],{"class":66,"line":745},[64,1438,157],{"class":124},[64,1440,1441,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461,1463,1465,1468],{"class":66,"line":776},[64,1442,137],{"class":107},[64,1444,140],{"class":111},[64,1446,143],{"class":107},[64,1448,169],{"class":111},[64,1450,1203],{"class":107},[64,1452,175],{"class":111},[64,1454,178],{"class":107},[64,1456,140],{"class":111},[64,1458,183],{"class":107},[64,1460,140],{"class":111},[64,1462,188],{"class":107},[64,1464,191],{"class":111},[64,1466,1467],{"class":194},"1",[64,1469,198],{"class":111},[64,1471,1472,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496,1499],{"class":66,"line":781},[64,1473,137],{"class":107},[64,1475,140],{"class":111},[64,1477,143],{"class":107},[64,1479,169],{"class":111},[64,1481,1209],{"class":107},[64,1483,175],{"class":111},[64,1485,178],{"class":107},[64,1487,140],{"class":111},[64,1489,183],{"class":107},[64,1491,140],{"class":111},[64,1493,188],{"class":107},[64,1495,191],{"class":111},[64,1497,1498],{"class":194},"3",[64,1500,198],{"class":111},[64,1502,1503],{"class":66,"line":799},[64,1504,98],{"emptyLinePlaceholder":97},[64,1506,1507,1509,1511,1513,1516,1518,1520],{"class":66,"line":804},[64,1508,209],{"class":107},[64,1510,212],{"class":111},[64,1512,215],{"class":70},[64,1514,1515],{"class":74}," \"main：注册 timer1，1 秒后到期\"",[64,1517,221],{"class":70},[64,1519,224],{"class":107},[64,1521,227],{"class":111},[64,1523,1524],{"class":66,"line":810},[64,1525,807],{"class":124},[64,1527,1528,1531,1533,1535,1537,1539,1541],{"class":66,"line":840},[64,1529,1530],{"class":111},"    timer1.",[64,1532,815],{"class":107},[64,1534,191],{"class":111},[64,1536,178],{"class":107},[64,1538,140],{"class":111},[64,1540,824],{"class":107},[64,1542,1543],{"class":111},"(on_timer,\n",[64,1545,1546,1549,1551,1553],{"class":66,"line":845},[64,1547,1548],{"class":107},"                                std",[64,1550,140],{"class":111},[64,1552,834],{"class":107},[64,1554,1555],{"class":111},"::_1,\n",[64,1557,1558,1560,1562,1564,1566,1569],{"class":66,"line":863},[64,1559,1548],{"class":107},[64,1561,140],{"class":111},[64,1563,1306],{"class":107},[64,1565,191],{"class":111},[64,1567,1568],{"class":74},"\"timer1\"",[64,1570,1571],{"class":111},")));\n",[64,1573,1574],{"class":66,"line":881},[64,1575,98],{"emptyLinePlaceholder":97},[64,1577,1578,1580,1582,1584,1587,1589,1591],{"class":66,"line":886},[64,1579,209],{"class":107},[64,1581,212],{"class":111},[64,1583,215],{"class":70},[64,1585,1586],{"class":74}," \"main：注册 timer2，3 秒后到期\"",[64,1588,221],{"class":70},[64,1590,224],{"class":107},[64,1592,227],{"class":111},[64,1594,1595,1598,1600,1602,1604,1606,1608],{"class":66,"line":897},[64,1596,1597],{"class":111},"    timer2.",[64,1599,815],{"class":107},[64,1601,191],{"class":111},[64,1603,178],{"class":107},[64,1605,140],{"class":111},[64,1607,824],{"class":107},[64,1609,1543],{"class":111},[64,1611,1612,1614,1616,1618],{"class":66,"line":902},[64,1613,1548],{"class":107},[64,1615,140],{"class":111},[64,1617,834],{"class":107},[64,1619,1555],{"class":111},[64,1621,1622,1624,1626,1628,1630,1633],{"class":66,"line":920},[64,1623,1548],{"class":107},[64,1625,140],{"class":111},[64,1627,1306],{"class":107},[64,1629,191],{"class":111},[64,1631,1632],{"class":74},"\"timer2\"",[64,1634,1571],{"class":111},[64,1636,1637],{"class":66,"line":925},[64,1638,98],{"emptyLinePlaceholder":97},[64,1640,1641,1643,1645,1647,1650,1652,1654],{"class":66,"line":934},[64,1642,209],{"class":107},[64,1644,212],{"class":111},[64,1646,215],{"class":70},[64,1648,1649],{"class":74}," \"main：调用 io.run()\"",[64,1651,221],{"class":70},[64,1653,224],{"class":107},[64,1655,227],{"class":111},[64,1657,1659],{"class":66,"line":1658},41,[64,1660,98],{"emptyLinePlaceholder":97},[64,1662,1664,1666,1668,1671,1674,1677,1680,1682],{"class":66,"line":1663},42,[64,1665,209],{"class":107},[64,1667,140],{"class":111},[64,1669,1670],{"class":70},"size_t",[64,1672,1673],{"class":111}," count ",[64,1675,1676],{"class":70},"=",[64,1678,1679],{"class":111}," io.",[64,1681,892],{"class":107},[64,1683,250],{"class":111},[64,1685,1687],{"class":66,"line":1686},43,[64,1688,98],{"emptyLinePlaceholder":97},[64,1690,1692,1694,1696,1698,1701,1703,1705,1707,1710,1712,1714],{"class":66,"line":1691},44,[64,1693,209],{"class":107},[64,1695,212],{"class":111},[64,1697,215],{"class":70},[64,1699,1700],{"class":74}," \"main：io.run() 返回，一共执行了 \"",[64,1702,221],{"class":70},[64,1704,1673],{"class":111},[64,1706,215],{"class":70},[64,1708,1709],{"class":74}," \" 个回调\"",[64,1711,221],{"class":70},[64,1713,224],{"class":107},[64,1715,227],{"class":111},[64,1717,1719],{"class":66,"line":1718},45,[64,1720,98],{"emptyLinePlaceholder":97},[64,1722,1724,1726,1728],{"class":66,"line":1723},46,[64,1725,284],{"class":70},[64,1727,287],{"class":194},[64,1729,290],{"class":111},[64,1731,1733],{"class":66,"line":1732},47,[64,1734,296],{"class":111},[13,1736,1737,303],{},[300,1738,302],{},[45,1740,306],{"id":1741},"编译运行-2",[55,1743,1745],{"className":309,"code":1744,"language":311,"meta":60,"style":60},"g++ demo3_two_timers.cpp -o demo3_two_timers -std=c++17 -lboost_system -pthread\n./demo3_two_timers\n",[21,1746,1747,1765],{"__ignoreMap":60},[64,1748,1749,1751,1754,1756,1759,1761,1763],{"class":66,"line":67},[64,1750,318],{"class":107},[64,1752,1753],{"class":74}," demo3_two_timers.cpp",[64,1755,324],{"class":194},[64,1757,1758],{"class":74}," demo3_two_timers",[64,1760,330],{"class":194},[64,1762,333],{"class":194},[64,1764,336],{"class":194},[64,1766,1767],{"class":66,"line":78},[64,1768,1769],{"class":107},"./demo3_two_timers\n",[45,1771,344],{"id":1772},"运行输出与时间顺序-2",[13,1774,977],{},[55,1776,1779],{"className":1777,"code":1778,"language":350,"meta":60},[348],"main：注册 timer1，1 秒后到期\nmain：注册 timer2，3 秒后到期\nmain：调用 io.run()\n",[21,1780,1778],{"__ignoreMap":60},[13,1782,1783],{},"约 1 秒后输出：",[55,1785,1788],{"className":1786,"code":1787,"language":350,"meta":60},[348],"timer1 到期，执行回调\n",[21,1789,1787],{"__ignoreMap":60},[13,1791,1792],{},"再过约 2 秒，也就是程序启动后约 3 秒，输出：",[55,1794,1797],{"className":1795,"code":1796,"language":350,"meta":60},[348],"timer2 到期，执行回调\nmain：io.run() 返回，一共执行了 2 个回调\n",[21,1798,1796],{"__ignoreMap":60},[13,1800,364],{},[55,1802,1805],{"className":1803,"code":1804,"language":350,"meta":60},[348],"main：注册 timer1，1 秒后到期\nmain：注册 timer2，3 秒后到期\nmain：调用 io.run()\ntimer1 到期，执行回调\ntimer2 到期，执行回调\nmain：io.run() 返回，一共执行了 2 个回调\n",[21,1806,1804],{"__ignoreMap":60},[45,1808,373],{"id":1809},"本示例需要注意的点-2",[13,1811,1812],{},"两个 timer 不是两个线程。",[13,1814,1815,1816,1818,1819,1821,1822,1824],{},"本例只有一个线程，也就是主线程。",[21,1817,1203],{}," 和 ",[21,1820,1209],{}," 的回调都在调用 ",[21,1823,527],{}," 的这个主线程里执行。",[13,1826,1827],{},"真正的执行顺序是：",[55,1829,1832],{"className":1830,"code":1831,"language":350,"meta":60},[348],"主线程进入 io.run()\n等待事件\ntimer1 先到期 -> 调用 timer1 回调\n继续等待事件\ntimer2 后到期 -> 调用 timer2 回调\n没有任务了 -> io.run() 返回\n",[21,1833,1831],{"__ignoreMap":60},[45,1835,1837,1839],{"id":1836},"stdbind-里的固定参数",[21,1838,30],{}," 里的固定参数",[13,1841,1842],{},"这句：",[55,1844,1846],{"className":57,"code":1845,"language":59,"meta":60,"style":60},"std::bind(on_timer, std::placeholders::_1, std::string(\"timer1\"))\n",[21,1847,1848],{"__ignoreMap":60},[64,1849,1850,1852,1854,1856,1858,1860,1862,1864,1867,1869,1871,1873,1875,1877],{"class":66,"line":67},[64,1851,178],{"class":107},[64,1853,140],{"class":111},[64,1855,824],{"class":107},[64,1857,827],{"class":111},[64,1859,178],{"class":107},[64,1861,140],{"class":111},[64,1863,834],{"class":107},[64,1865,1866],{"class":111},"::_1, ",[64,1868,178],{"class":107},[64,1870,140],{"class":111},[64,1872,1306],{"class":107},[64,1874,191],{"class":111},[64,1876,1568],{"class":74},[64,1878,1879],{"class":111},"))\n",[13,1881,1882],{},"等价于提前准备了一个函数对象：",[55,1884,1887],{"className":1885,"code":1886,"language":350,"meta":60},[348],"未来 Asio 传入 ec 时，调用 on_timer(ec, \"timer1\")。\n",[21,1888,1886],{"__ignoreMap":60},[13,1890,1891,1894],{},[21,1892,1893],{},"_1"," 是未来由 Asio 传入的错误码。",[13,1896,1897,1899],{},[21,1898,1568],{}," 是现在就固定好的参数。",[33,1901],{},[36,1903,1905,1906,1908],{"id":1904},"示例-4普通-main-里写重复定时器","示例 4：普通 ",[21,1907,42],{}," 里写重复定时器",[45,1910,47],{"id":1911},"程序目标-3",[13,1913,1914],{},"实现一个每 1 秒打印一次的定时器，打印 5 次后结束。",[13,1916,1917],{},"这个例子很像机器人里的周期任务，例如：",[55,1919,1922],{"className":1920,"code":1921,"language":350,"meta":60},[348],"每 20ms 发送一次速度命令\n每 100ms 检查一次下位机心跳\n每 1s 打印一次通信状态\n",[21,1923,1921],{"__ignoreMap":60},[45,1925,53],{"id":1926},"完整代码-3",[55,1928,1930],{"className":57,"code":1929,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n\nvoid repeat_timer(const boost::system::error_code& ec,\n                  boost::asio::steady_timer* timer,\n                  int* count)\n{\n    if (ec)\n    {\n        std::cout \u003C\u003C \"repeat_timer 被取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return;\n    }\n\n    ++(*count);\n    std::cout \u003C\u003C \"第 \" \u003C\u003C *count \u003C\u003C \" 次定时器回调\" \u003C\u003C std::endl;\n\n    if (*count \u003C 5)\n    {\n        timer->expires_after(std::chrono::seconds(1));\n        timer->async_wait(std::bind(repeat_timer,\n                                    std::placeholders::_1,\n                                    timer,\n                                    count));\n    }\n    else\n    {\n        std::cout \u003C\u003C \"已经执行 5 次，不再重新注册定时器\" \u003C\u003C std::endl;\n    }\n}\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer(io, std::chrono::seconds(1));\n    int count = 0;\n\n    std::cout \u003C\u003C \"main：注册第 1 次定时器\" \u003C\u003C std::endl;\n\n    // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n    timer.async_wait(std::bind(repeat_timer,\n                               std::placeholders::_1,\n                               &timer,\n                               &count));\n\n    io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回，程序结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,1931,1932,1938,1944,1950,1956,1962,1966,1994,2016,2026,2030,2036,2040,2065,2071,2075,2079,2091,2121,2125,2144,2148,2174,2191,2202,2207,2212,2216,2221,2225,2242,2246,2250,2254,2262,2266,2270,2274,2284,2288,2318,2331,2335,2352,2356,2360,2376,2387,2396,2404,2409,2418,2423,2440,2445,2454],{"__ignoreMap":60},[64,1933,1934,1936],{"class":66,"line":67},[64,1935,71],{"class":70},[64,1937,75],{"class":74},[64,1939,1940,1942],{"class":66,"line":78},[64,1941,71],{"class":70},[64,1943,558],{"class":74},[64,1945,1946,1948],{"class":66,"line":86},[64,1947,71],{"class":70},[64,1949,83],{"class":74},[64,1951,1952,1954],{"class":66,"line":94},[64,1953,71],{"class":70},[64,1955,571],{"class":74},[64,1957,1958,1960],{"class":66,"line":101},[64,1959,71],{"class":70},[64,1961,91],{"class":74},[64,1963,1964],{"class":66,"line":115},[64,1965,98],{"emptyLinePlaceholder":97},[64,1967,1968,1970,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991],{"class":66,"line":121},[64,1969,490],{"class":70},[64,1971,1972],{"class":107}," repeat_timer",[64,1974,191],{"class":111},[64,1976,593],{"class":70},[64,1978,596],{"class":107},[64,1980,140],{"class":111},[64,1982,601],{"class":107},[64,1984,140],{"class":111},[64,1986,606],{"class":107},[64,1988,609],{"class":70},[64,1990,613],{"class":612},[64,1992,1993],{"class":111},",\n",[64,1995,1996,1999,2001,2003,2005,2008,2011,2014],{"class":66,"line":128},[64,1997,1998],{"class":107},"                  boost",[64,2000,140],{"class":111},[64,2002,143],{"class":107},[64,2004,140],{"class":111},[64,2006,2007],{"class":107},"steady_timer",[64,2009,2010],{"class":70},"*",[64,2012,2013],{"class":612}," timer",[64,2015,1993],{"class":111},[64,2017,2018,2021,2024],{"class":66,"line":134},[64,2019,2020],{"class":70},"                  int*",[64,2022,2023],{"class":612}," count",[64,2025,472],{"class":111},[64,2027,2028],{"class":66,"line":149},[64,2029,118],{"class":111},[64,2031,2032,2034],{"class":66,"line":154},[64,2033,624],{"class":70},[64,2035,627],{"class":111},[64,2037,2038],{"class":66,"line":160},[64,2039,632],{"class":111},[64,2041,2042,2044,2046,2048,2051,2053,2055,2057,2059,2061,2063],{"class":66,"line":201},[64,2043,637],{"class":107},[64,2045,212],{"class":111},[64,2047,215],{"class":70},[64,2049,2050],{"class":74}," \"repeat_timer 被取消：\"",[64,2052,221],{"class":70},[64,2054,649],{"class":111},[64,2056,652],{"class":107},[64,2058,655],{"class":111},[64,2060,215],{"class":70},[64,2062,224],{"class":107},[64,2064,227],{"class":111},[64,2066,2067,2069],{"class":66,"line":206},[64,2068,666],{"class":70},[64,2070,290],{"class":111},[64,2072,2073],{"class":66,"line":230},[64,2074,673],{"class":111},[64,2076,2077],{"class":66,"line":235},[64,2078,98],{"emptyLinePlaceholder":97},[64,2080,2081,2084,2086,2088],{"class":66,"line":241},[64,2082,2083],{"class":70},"    ++",[64,2085,191],{"class":111},[64,2087,2010],{"class":70},[64,2089,2090],{"class":111},"count);\n",[64,2092,2093,2095,2097,2099,2102,2104,2107,2110,2112,2115,2117,2119],{"class":66,"line":253},[64,2094,209],{"class":107},[64,2096,212],{"class":111},[64,2098,215],{"class":70},[64,2100,2101],{"class":74}," \"第 \"",[64,2103,221],{"class":70},[64,2105,2106],{"class":70}," *",[64,2108,2109],{"class":111},"count ",[64,2111,215],{"class":70},[64,2113,2114],{"class":74}," \" 次定时器回调\"",[64,2116,221],{"class":70},[64,2118,224],{"class":107},[64,2120,227],{"class":111},[64,2122,2123],{"class":66,"line":258},[64,2124,98],{"emptyLinePlaceholder":97},[64,2126,2127,2129,2132,2134,2136,2139,2142],{"class":66,"line":276},[64,2128,624],{"class":70},[64,2130,2131],{"class":111}," (",[64,2133,2010],{"class":70},[64,2135,2109],{"class":111},[64,2137,2138],{"class":70},"\u003C",[64,2140,2141],{"class":194}," 5",[64,2143,472],{"class":111},[64,2145,2146],{"class":66,"line":281},[64,2147,632],{"class":111},[64,2149,2150,2153,2156,2158,2160,2162,2164,2166,2168,2170,2172],{"class":66,"line":293},[64,2151,2152],{"class":111},"        timer->",[64,2154,2155],{"class":107},"expires_after",[64,2157,191],{"class":111},[64,2159,178],{"class":107},[64,2161,140],{"class":111},[64,2163,183],{"class":107},[64,2165,140],{"class":111},[64,2167,188],{"class":107},[64,2169,191],{"class":111},[64,2171,1467],{"class":194},[64,2173,198],{"class":111},[64,2175,2176,2178,2180,2182,2184,2186,2188],{"class":66,"line":735},[64,2177,2152],{"class":111},[64,2179,815],{"class":107},[64,2181,191],{"class":111},[64,2183,178],{"class":107},[64,2185,140],{"class":111},[64,2187,824],{"class":107},[64,2189,2190],{"class":111},"(repeat_timer,\n",[64,2192,2193,2196,2198,2200],{"class":66,"line":740},[64,2194,2195],{"class":107},"                                    std",[64,2197,140],{"class":111},[64,2199,834],{"class":107},[64,2201,1555],{"class":111},[64,2203,2204],{"class":66,"line":745},[64,2205,2206],{"class":111},"                                    timer,\n",[64,2208,2209],{"class":66,"line":776},[64,2210,2211],{"class":111},"                                    count));\n",[64,2213,2214],{"class":66,"line":781},[64,2215,673],{"class":111},[64,2217,2218],{"class":66,"line":799},[64,2219,2220],{"class":70},"    else\n",[64,2222,2223],{"class":66,"line":804},[64,2224,632],{"class":111},[64,2226,2227,2229,2231,2233,2236,2238,2240],{"class":66,"line":810},[64,2228,637],{"class":107},[64,2230,212],{"class":111},[64,2232,215],{"class":70},[64,2234,2235],{"class":74}," \"已经执行 5 次，不再重新注册定时器\"",[64,2237,221],{"class":70},[64,2239,224],{"class":107},[64,2241,227],{"class":111},[64,2243,2244],{"class":66,"line":840},[64,2245,673],{"class":111},[64,2247,2248],{"class":66,"line":845},[64,2249,296],{"class":111},[64,2251,2252],{"class":66,"line":863},[64,2253,98],{"emptyLinePlaceholder":97},[64,2255,2256,2258,2260],{"class":66,"line":881},[64,2257,104],{"class":70},[64,2259,108],{"class":107},[64,2261,112],{"class":111},[64,2263,2264],{"class":66,"line":886},[64,2265,118],{"class":111},[64,2267,2268],{"class":66,"line":897},[64,2269,125],{"class":124},[64,2271,2272],{"class":66,"line":902},[64,2273,131],{"class":124},[64,2275,2276,2278,2280,2282],{"class":66,"line":920},[64,2277,137],{"class":107},[64,2279,140],{"class":111},[64,2281,143],{"class":107},[64,2283,146],{"class":111},[64,2285,2286],{"class":66,"line":925},[64,2287,157],{"class":124},[64,2289,2290,2292,2294,2296,2298,2300,2302,2304,2306,2308,2310,2312,2314,2316],{"class":66,"line":934},[64,2291,137],{"class":107},[64,2293,140],{"class":111},[64,2295,143],{"class":107},[64,2297,169],{"class":111},[64,2299,172],{"class":107},[64,2301,175],{"class":111},[64,2303,178],{"class":107},[64,2305,140],{"class":111},[64,2307,183],{"class":107},[64,2309,140],{"class":111},[64,2311,188],{"class":107},[64,2313,191],{"class":111},[64,2315,1467],{"class":194},[64,2317,198],{"class":111},[64,2319,2320,2323,2325,2327,2329],{"class":66,"line":1658},[64,2321,2322],{"class":70},"    int",[64,2324,1673],{"class":111},[64,2326,1676],{"class":70},[64,2328,287],{"class":194},[64,2330,290],{"class":111},[64,2332,2333],{"class":66,"line":1663},[64,2334,98],{"emptyLinePlaceholder":97},[64,2336,2337,2339,2341,2343,2346,2348,2350],{"class":66,"line":1686},[64,2338,209],{"class":107},[64,2340,212],{"class":111},[64,2342,215],{"class":70},[64,2344,2345],{"class":74}," \"main：注册第 1 次定时器\"",[64,2347,221],{"class":70},[64,2349,224],{"class":107},[64,2351,227],{"class":111},[64,2353,2354],{"class":66,"line":1691},[64,2355,98],{"emptyLinePlaceholder":97},[64,2357,2358],{"class":66,"line":1718},[64,2359,807],{"class":124},[64,2361,2362,2364,2366,2368,2370,2372,2374],{"class":66,"line":1723},[64,2363,244],{"class":111},[64,2365,815],{"class":107},[64,2367,191],{"class":111},[64,2369,178],{"class":107},[64,2371,140],{"class":111},[64,2373,824],{"class":107},[64,2375,2190],{"class":111},[64,2377,2378,2381,2383,2385],{"class":66,"line":1732},[64,2379,2380],{"class":107},"                               std",[64,2382,140],{"class":111},[64,2384,834],{"class":107},[64,2386,1555],{"class":111},[64,2388,2390,2393],{"class":66,"line":2389},48,[64,2391,2392],{"class":70},"                               &",[64,2394,2395],{"class":111},"timer,\n",[64,2397,2399,2401],{"class":66,"line":2398},49,[64,2400,2392],{"class":70},[64,2402,2403],{"class":111},"count));\n",[64,2405,2407],{"class":66,"line":2406},50,[64,2408,98],{"emptyLinePlaceholder":97},[64,2410,2412,2414,2416],{"class":66,"line":2411},51,[64,2413,889],{"class":111},[64,2415,892],{"class":107},[64,2417,250],{"class":111},[64,2419,2421],{"class":66,"line":2420},52,[64,2422,98],{"emptyLinePlaceholder":97},[64,2424,2426,2428,2430,2432,2434,2436,2438],{"class":66,"line":2425},53,[64,2427,209],{"class":107},[64,2429,212],{"class":111},[64,2431,215],{"class":70},[64,2433,911],{"class":74},[64,2435,221],{"class":70},[64,2437,224],{"class":107},[64,2439,227],{"class":111},[64,2441,2443],{"class":66,"line":2442},54,[64,2444,98],{"emptyLinePlaceholder":97},[64,2446,2448,2450,2452],{"class":66,"line":2447},55,[64,2449,284],{"class":70},[64,2451,287],{"class":194},[64,2453,290],{"class":111},[64,2455,2457],{"class":66,"line":2456},56,[64,2458,296],{"class":111},[13,2460,2461,303],{},[300,2462,302],{},[45,2464,306],{"id":2465},"编译运行-3",[55,2467,2469],{"className":309,"code":2468,"language":311,"meta":60,"style":60},"g++ demo4_repeat_timer.cpp -o demo4_repeat_timer -std=c++17 -lboost_system -pthread\n./demo4_repeat_timer\n",[21,2470,2471,2489],{"__ignoreMap":60},[64,2472,2473,2475,2478,2480,2483,2485,2487],{"class":66,"line":67},[64,2474,318],{"class":107},[64,2476,2477],{"class":74}," demo4_repeat_timer.cpp",[64,2479,324],{"class":194},[64,2481,2482],{"class":74}," demo4_repeat_timer",[64,2484,330],{"class":194},[64,2486,333],{"class":194},[64,2488,336],{"class":194},[64,2490,2491],{"class":66,"line":78},[64,2492,2493],{"class":107},"./demo4_repeat_timer\n",[45,2495,344],{"id":2496},"运行输出与时间顺序-3",[13,2498,977],{},[55,2500,2503],{"className":2501,"code":2502,"language":350,"meta":60},[348],"main：注册第 1 次定时器\n",[21,2504,2502],{"__ignoreMap":60},[13,2506,2507],{},"约 1 秒后：",[55,2509,2512],{"className":2510,"code":2511,"language":350,"meta":60},[348],"第 1 次定时器回调\n",[21,2513,2511],{"__ignoreMap":60},[13,2515,2516],{},"之后每隔约 1 秒输出一次：",[55,2518,2521],{"className":2519,"code":2520,"language":350,"meta":60},[348],"第 2 次定时器回调\n第 3 次定时器回调\n第 4 次定时器回调\n第 5 次定时器回调\n已经执行 5 次，不再重新注册定时器\nmain：io.run() 返回，程序结束\n",[21,2522,2520],{"__ignoreMap":60},[13,2524,364],{},[55,2526,2529],{"className":2527,"code":2528,"language":350,"meta":60},[348],"main：注册第 1 次定时器\n第 1 次定时器回调\n第 2 次定时器回调\n第 3 次定时器回调\n第 4 次定时器回调\n第 5 次定时器回调\n已经执行 5 次，不再重新注册定时器\nmain：io.run() 返回，程序结束\n",[21,2530,2528],{"__ignoreMap":60},[45,2532,373],{"id":2533},"本示例需要注意的点-3",[13,2535,2536,2537,2540,2541,491],{},"重复定时器不是 ",[21,2538,2539],{},"while"," 循环里 ",[21,2542,2543],{},"sleep",[13,2545,2546],{},"异步写法是：",[55,2548,2551],{"className":2549,"code":2550,"language":350,"meta":60},[348],"第一次 async_wait\n第 1 次回调里重新设置 expires_after\n第 1 次回调里再次 async_wait\n第 2 次回调里再次注册\n……\n",[21,2552,2550],{"__ignoreMap":60},[13,2554,2555],{},"也就是“每次回调结束前，决定要不要注册下一次”。",[45,2557,2558],{"id":2558},"指针生命周期说明",[13,2560,2561],{},"本例里传了：",[55,2563,2565],{"className":57,"code":2564,"language":59,"meta":60,"style":60},"&timer\n&count\n",[21,2566,2567,2574],{"__ignoreMap":60},[64,2568,2569,2571],{"class":66,"line":67},[64,2570,609],{"class":70},[64,2572,2573],{"class":111},"timer\n",[64,2575,2576,2578],{"class":66,"line":78},[64,2577,609],{"class":70},[64,2579,2580],{"class":111},"count\n",[13,2582,2583,2584,2587],{},"这是为了让 ",[21,2585,2586],{},"repeat_timer()"," 能修改同一个 timer 和 count。",[13,2589,2590],{},"这个写法在本例中是安全的，因为：",[55,2592,2595],{"className":2593,"code":2594,"language":350,"meta":60},[348],"timer 和 count 都是 main() 里的局部变量\nmain() 会卡在 io.run()\nio.run() 返回前，timer 和 count 都不会析构\n",[21,2596,2594],{"__ignoreMap":60},[13,2598,2599],{},"但是工程里更推荐把它封装成类，见下一个示例。",[33,2601],{},[36,2603,2605],{"id":2604},"示例-5类里写单个异步定时器","示例 5：类里写单个异步定时器",[45,2607,47],{"id":2608},"程序目标-4",[13,2610,2611],{},"把示例 2 改成类封装版本。",[13,2613,2614],{},"类封装是机器人项目里更常见的写法，例如：",[55,2616,2619],{"className":2617,"code":2618,"language":350,"meta":60},[348],"SerialDriver 类\nTcpClient 类\nUdpReceiver 类\nRobotController 类\n",[21,2620,2618],{"__ignoreMap":60},[45,2622,53],{"id":2623},"完整代码-4",[55,2625,2627],{"className":57,"code":2626,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n\nclass Printer\n{\npublic:\n    explicit Printer(boost::asio::io_context& io)\n        : timer_(io, std::chrono::seconds(2))\n    {\n        std::cout \u003C\u003C \"Printer 构造：注册 2 秒定时器\" \u003C\u003C std::endl;\n\n        // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n        timer_.async_wait(std::bind(&Printer::on_timer,\n                                    this,\n                                    std::placeholders::_1));\n    }\n\nprivate:\n    void on_timer(const boost::system::error_code& ec)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"Printer::on_timer 被取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        std::cout \u003C\u003C \"Printer::on_timer：2 秒到了\" \u003C\u003C std::endl;\n    }\n\nprivate:\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer_;\n};\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    Printer printer(io);\n\n    std::cout \u003C\u003C \"main：准备调用 io.run()\" \u003C\u003C std::endl;\n\n    io.run();\n\n    std::cout \u003C\u003C \"main：io.run() 返回\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,2628,2629,2635,2641,2647,2653,2659,2663,2671,2675,2680,2708,2734,2738,2755,2759,2764,2789,2796,2806,2810,2814,2819,2846,2850,2857,2862,2888,2895,2900,2904,2921,2925,2929,2933,2937,2948,2953,2957,2965,2969,2973,2977,2987,2991,3002,3006,3022,3026,3034,3038,3055,3059,3067],{"__ignoreMap":60},[64,2630,2631,2633],{"class":66,"line":67},[64,2632,71],{"class":70},[64,2634,75],{"class":74},[64,2636,2637,2639],{"class":66,"line":78},[64,2638,71],{"class":70},[64,2640,558],{"class":74},[64,2642,2643,2645],{"class":66,"line":86},[64,2644,71],{"class":70},[64,2646,83],{"class":74},[64,2648,2649,2651],{"class":66,"line":94},[64,2650,71],{"class":70},[64,2652,571],{"class":74},[64,2654,2655,2657],{"class":66,"line":101},[64,2656,71],{"class":70},[64,2658,91],{"class":74},[64,2660,2661],{"class":66,"line":115},[64,2662,98],{"emptyLinePlaceholder":97},[64,2664,2665,2668],{"class":66,"line":121},[64,2666,2667],{"class":70},"class",[64,2669,2670],{"class":107}," Printer\n",[64,2672,2673],{"class":66,"line":128},[64,2674,118],{"class":111},[64,2676,2677],{"class":66,"line":134},[64,2678,2679],{"class":70},"public:\n",[64,2681,2682,2685,2688,2690,2693,2695,2697,2699,2701,2703,2706],{"class":66,"line":149},[64,2683,2684],{"class":70},"    explicit",[64,2686,2687],{"class":107}," Printer",[64,2689,191],{"class":111},[64,2691,2692],{"class":107},"boost",[64,2694,140],{"class":111},[64,2696,143],{"class":107},[64,2698,140],{"class":111},[64,2700,447],{"class":107},[64,2702,609],{"class":70},[64,2704,2705],{"class":612}," io",[64,2707,472],{"class":111},[64,2709,2710,2713,2716,2718,2720,2722,2724,2726,2728,2730,2732],{"class":66,"line":154},[64,2711,2712],{"class":111},"        : ",[64,2714,2715],{"class":107},"timer_",[64,2717,175],{"class":111},[64,2719,178],{"class":107},[64,2721,140],{"class":111},[64,2723,183],{"class":107},[64,2725,140],{"class":111},[64,2727,188],{"class":107},[64,2729,191],{"class":111},[64,2731,195],{"class":194},[64,2733,1879],{"class":111},[64,2735,2736],{"class":66,"line":160},[64,2737,632],{"class":111},[64,2739,2740,2742,2744,2746,2749,2751,2753],{"class":66,"line":201},[64,2741,637],{"class":107},[64,2743,212],{"class":111},[64,2745,215],{"class":70},[64,2747,2748],{"class":74}," \"Printer 构造：注册 2 秒定时器\"",[64,2750,221],{"class":70},[64,2752,224],{"class":107},[64,2754,227],{"class":111},[64,2756,2757],{"class":66,"line":206},[64,2758,98],{"emptyLinePlaceholder":97},[64,2760,2761],{"class":66,"line":230},[64,2762,2763],{"class":124},"        // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n",[64,2765,2766,2769,2771,2773,2775,2777,2779,2781,2783,2786],{"class":66,"line":235},[64,2767,2768],{"class":111},"        timer_.",[64,2770,815],{"class":107},[64,2772,191],{"class":111},[64,2774,178],{"class":107},[64,2776,140],{"class":111},[64,2778,824],{"class":107},[64,2780,191],{"class":111},[64,2782,609],{"class":70},[64,2784,2785],{"class":107},"Printer",[64,2787,2788],{"class":111},"::on_timer,\n",[64,2790,2791,2794],{"class":66,"line":241},[64,2792,2793],{"class":194},"                                    this",[64,2795,1993],{"class":111},[64,2797,2798,2800,2802,2804],{"class":66,"line":253},[64,2799,2195],{"class":107},[64,2801,140],{"class":111},[64,2803,834],{"class":107},[64,2805,837],{"class":111},[64,2807,2808],{"class":66,"line":258},[64,2809,673],{"class":111},[64,2811,2812],{"class":66,"line":276},[64,2813,98],{"emptyLinePlaceholder":97},[64,2815,2816],{"class":66,"line":281},[64,2817,2818],{"class":70},"private:\n",[64,2820,2821,2824,2826,2828,2830,2832,2834,2836,2838,2840,2842,2844],{"class":66,"line":293},[64,2822,2823],{"class":70},"    void",[64,2825,588],{"class":107},[64,2827,191],{"class":111},[64,2829,593],{"class":70},[64,2831,596],{"class":107},[64,2833,140],{"class":111},[64,2835,601],{"class":107},[64,2837,140],{"class":111},[64,2839,606],{"class":107},[64,2841,609],{"class":70},[64,2843,613],{"class":612},[64,2845,472],{"class":111},[64,2847,2848],{"class":66,"line":735},[64,2849,632],{"class":111},[64,2851,2852,2855],{"class":66,"line":740},[64,2853,2854],{"class":70},"        if",[64,2856,627],{"class":111},[64,2858,2859],{"class":66,"line":745},[64,2860,2861],{"class":111},"        {\n",[64,2863,2864,2867,2869,2871,2874,2876,2878,2880,2882,2884,2886],{"class":66,"line":776},[64,2865,2866],{"class":107},"            std",[64,2868,212],{"class":111},[64,2870,215],{"class":70},[64,2872,2873],{"class":74}," \"Printer::on_timer 被取消：\"",[64,2875,221],{"class":70},[64,2877,649],{"class":111},[64,2879,652],{"class":107},[64,2881,655],{"class":111},[64,2883,215],{"class":70},[64,2885,224],{"class":107},[64,2887,227],{"class":111},[64,2889,2890,2893],{"class":66,"line":781},[64,2891,2892],{"class":70},"            return",[64,2894,290],{"class":111},[64,2896,2897],{"class":66,"line":799},[64,2898,2899],{"class":111},"        }\n",[64,2901,2902],{"class":66,"line":804},[64,2903,98],{"emptyLinePlaceholder":97},[64,2905,2906,2908,2910,2912,2915,2917,2919],{"class":66,"line":810},[64,2907,637],{"class":107},[64,2909,212],{"class":111},[64,2911,215],{"class":70},[64,2913,2914],{"class":74}," \"Printer::on_timer：2 秒到了\"",[64,2916,221],{"class":70},[64,2918,224],{"class":107},[64,2920,227],{"class":111},[64,2922,2923],{"class":66,"line":840},[64,2924,673],{"class":111},[64,2926,2927],{"class":66,"line":845},[64,2928,98],{"emptyLinePlaceholder":97},[64,2930,2931],{"class":66,"line":863},[64,2932,2818],{"class":70},[64,2934,2935],{"class":66,"line":881},[64,2936,157],{"class":124},[64,2938,2939,2941,2943,2945],{"class":66,"line":886},[64,2940,137],{"class":107},[64,2942,140],{"class":111},[64,2944,143],{"class":107},[64,2946,2947],{"class":111},"::steady_timer timer_;\n",[64,2949,2950],{"class":66,"line":897},[64,2951,2952],{"class":111},"};\n",[64,2954,2955],{"class":66,"line":902},[64,2956,98],{"emptyLinePlaceholder":97},[64,2958,2959,2961,2963],{"class":66,"line":920},[64,2960,104],{"class":70},[64,2962,108],{"class":107},[64,2964,112],{"class":111},[64,2966,2967],{"class":66,"line":925},[64,2968,118],{"class":111},[64,2970,2971],{"class":66,"line":934},[64,2972,125],{"class":124},[64,2974,2975],{"class":66,"line":1658},[64,2976,131],{"class":124},[64,2978,2979,2981,2983,2985],{"class":66,"line":1663},[64,2980,137],{"class":107},[64,2982,140],{"class":111},[64,2984,143],{"class":107},[64,2986,146],{"class":111},[64,2988,2989],{"class":66,"line":1686},[64,2990,98],{"emptyLinePlaceholder":97},[64,2992,2993,2996,2999],{"class":66,"line":1691},[64,2994,2995],{"class":111},"    Printer ",[64,2997,2998],{"class":107},"printer",[64,3000,3001],{"class":111},"(io);\n",[64,3003,3004],{"class":66,"line":1718},[64,3005,98],{"emptyLinePlaceholder":97},[64,3007,3008,3010,3012,3014,3016,3018,3020],{"class":66,"line":1723},[64,3009,209],{"class":107},[64,3011,212],{"class":111},[64,3013,215],{"class":70},[64,3015,872],{"class":74},[64,3017,221],{"class":70},[64,3019,224],{"class":107},[64,3021,227],{"class":111},[64,3023,3024],{"class":66,"line":1732},[64,3025,98],{"emptyLinePlaceholder":97},[64,3027,3028,3030,3032],{"class":66,"line":2389},[64,3029,889],{"class":111},[64,3031,892],{"class":107},[64,3033,250],{"class":111},[64,3035,3036],{"class":66,"line":2398},[64,3037,98],{"emptyLinePlaceholder":97},[64,3039,3040,3042,3044,3046,3049,3051,3053],{"class":66,"line":2406},[64,3041,209],{"class":107},[64,3043,212],{"class":111},[64,3045,215],{"class":70},[64,3047,3048],{"class":74}," \"main：io.run() 返回\"",[64,3050,221],{"class":70},[64,3052,224],{"class":107},[64,3054,227],{"class":111},[64,3056,3057],{"class":66,"line":2411},[64,3058,98],{"emptyLinePlaceholder":97},[64,3060,3061,3063,3065],{"class":66,"line":2420},[64,3062,284],{"class":70},[64,3064,287],{"class":194},[64,3066,290],{"class":111},[64,3068,3069],{"class":66,"line":2425},[64,3070,296],{"class":111},[13,3072,3073,303],{},[300,3074,302],{},[45,3076,306],{"id":3077},"编译运行-4",[55,3079,3081],{"className":309,"code":3080,"language":311,"meta":60,"style":60},"g++ demo5_class_timer.cpp -o demo5_class_timer -std=c++17 -lboost_system -pthread\n./demo5_class_timer\n",[21,3082,3083,3101],{"__ignoreMap":60},[64,3084,3085,3087,3090,3092,3095,3097,3099],{"class":66,"line":67},[64,3086,318],{"class":107},[64,3088,3089],{"class":74}," demo5_class_timer.cpp",[64,3091,324],{"class":194},[64,3093,3094],{"class":74}," demo5_class_timer",[64,3096,330],{"class":194},[64,3098,333],{"class":194},[64,3100,336],{"class":194},[64,3102,3103],{"class":66,"line":78},[64,3104,3105],{"class":107},"./demo5_class_timer\n",[45,3107,344],{"id":3108},"运行输出与时间顺序-4",[13,3110,977],{},[55,3112,3115],{"className":3113,"code":3114,"language":350,"meta":60},[348],"Printer 构造：注册 2 秒定时器\nmain：准备调用 io.run()\n",[21,3116,3114],{"__ignoreMap":60},[13,3118,3119],{},"约 2 秒后输出：",[55,3121,3124],{"className":3122,"code":3123,"language":350,"meta":60},[348],"Printer::on_timer：2 秒到了\nmain：io.run() 返回\n",[21,3125,3123],{"__ignoreMap":60},[13,3127,364],{},[55,3129,3132],{"className":3130,"code":3131,"language":350,"meta":60},[348],"Printer 构造：注册 2 秒定时器\nmain：准备调用 io.run()\nPrinter::on_timer：2 秒到了\nmain：io.run() 返回\n",[21,3133,3131],{"__ignoreMap":60},[45,3135,3136],{"id":3136},"构造函数初始化列表说明",[13,3138,3139],{},"这段：",[55,3141,3143],{"className":57,"code":3142,"language":59,"meta":60,"style":60},"explicit Printer(boost::asio::io_context& io)\n    : timer_(io, std::chrono::seconds(2))\n{\n}\n",[21,3144,3145,3168,3193,3197],{"__ignoreMap":60},[64,3146,3147,3150,3152,3154,3156,3158,3160,3163,3165],{"class":66,"line":67},[64,3148,3149],{"class":70},"explicit",[64,3151,2687],{"class":107},[64,3153,191],{"class":111},[64,3155,2692],{"class":107},[64,3157,140],{"class":111},[64,3159,143],{"class":107},[64,3161,3162],{"class":111},"::io_context",[64,3164,609],{"class":70},[64,3166,3167],{"class":111}," io)\n",[64,3169,3170,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191],{"class":66,"line":78},[64,3171,3172],{"class":111},"    : ",[64,3174,2715],{"class":107},[64,3176,175],{"class":111},[64,3178,178],{"class":107},[64,3180,140],{"class":111},[64,3182,183],{"class":107},[64,3184,140],{"class":111},[64,3186,188],{"class":107},[64,3188,191],{"class":111},[64,3190,195],{"class":194},[64,3192,1879],{"class":111},[64,3194,3195],{"class":66,"line":86},[64,3196,118],{"class":111},[64,3198,3199],{"class":66,"line":94},[64,3200,296],{"class":111},[13,3202,3203],{},"冒号后面叫“构造函数初始化列表”。",[13,3205,3206,3207,491],{},"它的作用是：在进入构造函数大括号之前，直接构造成员变量 ",[21,3208,2715],{},[13,3210,3211,3212,3215,3216,491],{},"为什么这里必须这么写？因为 ",[21,3213,3214],{},"boost::asio::steady_timer"," 没有一个适合你先默认构造、再赋值的简单写法。它需要在构造时就知道自己属于哪个 ",[21,3217,447],{},[45,3219,3220],{"id":3220},"成员函数绑定说明",[13,3222,1842],{},[55,3224,3226],{"className":57,"code":3225,"language":59,"meta":60,"style":60},"timer_.async_wait(std::bind(&Printer::on_timer,\n                            this,\n                            std::placeholders::_1));\n",[21,3227,3228,3251,3258],{"__ignoreMap":60},[64,3229,3230,3233,3235,3237,3239,3241,3243,3245,3247,3249],{"class":66,"line":67},[64,3231,3232],{"class":111},"timer_.",[64,3234,815],{"class":107},[64,3236,191],{"class":111},[64,3238,178],{"class":107},[64,3240,140],{"class":111},[64,3242,824],{"class":107},[64,3244,191],{"class":111},[64,3246,609],{"class":70},[64,3248,2785],{"class":107},[64,3250,2788],{"class":111},[64,3252,3253,3256],{"class":66,"line":78},[64,3254,3255],{"class":194},"                            this",[64,3257,1993],{"class":111},[64,3259,3260,3263,3265,3267],{"class":66,"line":86},[64,3261,3262],{"class":107},"                            std",[64,3264,140],{"class":111},[64,3266,834],{"class":107},[64,3268,837],{"class":111},[13,3270,3271],{},"含义是：",[55,3273,3276],{"className":3274,"code":3275,"language":350,"meta":60},[348],"定时器到期后，调用 this->on_timer(ec)。\n",[21,3277,3275],{"__ignoreMap":60},[13,3279,3280,3281,3284],{},"为什么要写 ",[21,3282,3283],{},"&Printer::on_timer","？",[13,3286,3287,3288,3290],{},"因为 ",[21,3289,1107],{}," 是成员函数，不是普通全局函数。成员函数必须依赖某个对象才能调用。",[13,3292,3293,3294,3284],{},"为什么要传 ",[21,3295,3296],{},"this",[13,3298,3287,3299,3301,3302,3304],{},[21,3300,3296],{}," 表示当前这个 ",[21,3303,2785],{}," 对象。",[45,3306,3307],{"id":3307},"易错点",[13,3309,3310],{},"不要写成：",[55,3312,3314],{"className":57,"code":3313,"language":59,"meta":60,"style":60},"std::bind(on_timer, std::placeholders::_1)\n",[21,3315,3316],{"__ignoreMap":60},[64,3317,3318,3320,3322,3324,3326,3328,3330,3332],{"class":66,"line":67},[64,3319,178],{"class":107},[64,3321,140],{"class":111},[64,3323,824],{"class":107},[64,3325,827],{"class":111},[64,3327,178],{"class":107},[64,3329,140],{"class":111},[64,3331,834],{"class":107},[64,3333,3334],{"class":111},"::_1)\n",[13,3336,3287,3337,3339],{},[21,3338,1107],{}," 是成员函数，不是普通函数。",[13,3341,3342,3343,3345],{},"也不要漏掉 ",[21,3344,3296],{},"：",[55,3347,3349],{"className":57,"code":3348,"language":59,"meta":60,"style":60},"std::bind(&Printer::on_timer, std::placeholders::_1)\n",[21,3350,3351],{"__ignoreMap":60},[64,3352,3353,3355,3357,3359,3361,3363,3365,3368,3370,3372,3374],{"class":66,"line":67},[64,3354,178],{"class":107},[64,3356,140],{"class":111},[64,3358,824],{"class":107},[64,3360,191],{"class":111},[64,3362,609],{"class":70},[64,3364,2785],{"class":107},[64,3366,3367],{"class":111},"::on_timer, ",[64,3369,178],{"class":107},[64,3371,140],{"class":111},[64,3373,834],{"class":107},[64,3375,3334],{"class":111},[13,3377,3378,3379,491],{},"这样不知道要调用哪个对象的 ",[21,3380,3381],{},"on_timer()",[33,3383],{},[36,3385,3387],{"id":3386},"示例-6类里写两个定时器","示例 6：类里写两个定时器",[45,3389,47],{"id":3390},"程序目标-5",[13,3392,3393],{},"类里同时维护两个 timer：",[511,3395,3396,3402,3408],{},[514,3397,3398,3401],{},[21,3399,3400],{},"timer1_"," 1 秒后执行；",[514,3403,3404,3407],{},[21,3405,3406],{},"timer2_"," 3 秒后执行；",[514,3409,3410],{},"用这个例子看清楚“两个异步任务不等于两个线程”。",[45,3412,53],{"id":3413},"完整代码-5",[55,3415,3417],{"className":57,"code":3416,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n\nclass TwoTimers\n{\npublic:\n    explicit TwoTimers(boost::asio::io_context& io)\n        : timer1_(io, std::chrono::seconds(1)),\n          timer2_(io, std::chrono::seconds(3))\n    {\n        std::cout \u003C\u003C \"TwoTimers 构造：注册 timer1 和 timer2\" \u003C\u003C std::endl;\n\n        // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n        timer1_.async_wait(std::bind(&TwoTimers::on_timer1,\n                                     this,\n                                     std::placeholders::_1));\n\n        timer2_.async_wait(std::bind(&TwoTimers::on_timer2,\n                                     this,\n                                     std::placeholders::_1));\n    }\n\nprivate:\n    void on_timer1(const boost::system::error_code& ec)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"timer1 取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        std::cout \u003C\u003C \"timer1：1 秒到了\" \u003C\u003C std::endl;\n    }\n\n    void on_timer2(const boost::system::error_code& ec)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"timer2 取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        std::cout \u003C\u003C \"timer2：3 秒到了\" \u003C\u003C std::endl;\n    }\n\nprivate:\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer1_;\n    boost::asio::steady_timer timer2_;\n};\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    TwoTimers app(io);\n\n    std::cout \u003C\u003C \"main：调用 io.run()\" \u003C\u003C std::endl;\n\n    io.run();\n\n    std::cout \u003C\u003C \"main：两个定时器都执行完，io.run() 返回\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,3418,3419,3425,3431,3437,3443,3449,3453,3460,3464,3468,3493,3518,3541,3545,3562,3566,3570,3595,3602,3613,3617,3641,3647,3657,3661,3665,3669,3696,3700,3706,3710,3735,3741,3745,3749,3766,3770,3774,3801,3805,3811,3815,3840,3846,3850,3854,3871,3875,3879,3883,3887,3898,3909,3913,3917,3925,3929,3934,3939,3950,3961,3966,3983,3988,3997,4002,4020,4025,4034],{"__ignoreMap":60},[64,3420,3421,3423],{"class":66,"line":67},[64,3422,71],{"class":70},[64,3424,75],{"class":74},[64,3426,3427,3429],{"class":66,"line":78},[64,3428,71],{"class":70},[64,3430,558],{"class":74},[64,3432,3433,3435],{"class":66,"line":86},[64,3434,71],{"class":70},[64,3436,83],{"class":74},[64,3438,3439,3441],{"class":66,"line":94},[64,3440,71],{"class":70},[64,3442,571],{"class":74},[64,3444,3445,3447],{"class":66,"line":101},[64,3446,71],{"class":70},[64,3448,91],{"class":74},[64,3450,3451],{"class":66,"line":115},[64,3452,98],{"emptyLinePlaceholder":97},[64,3454,3455,3457],{"class":66,"line":121},[64,3456,2667],{"class":70},[64,3458,3459],{"class":107}," TwoTimers\n",[64,3461,3462],{"class":66,"line":128},[64,3463,118],{"class":111},[64,3465,3466],{"class":66,"line":134},[64,3467,2679],{"class":70},[64,3469,3470,3472,3475,3477,3479,3481,3483,3485,3487,3489,3491],{"class":66,"line":149},[64,3471,2684],{"class":70},[64,3473,3474],{"class":107}," TwoTimers",[64,3476,191],{"class":111},[64,3478,2692],{"class":107},[64,3480,140],{"class":111},[64,3482,143],{"class":107},[64,3484,140],{"class":111},[64,3486,447],{"class":107},[64,3488,609],{"class":70},[64,3490,2705],{"class":612},[64,3492,472],{"class":111},[64,3494,3495,3497,3499,3501,3503,3505,3507,3509,3511,3513,3515],{"class":66,"line":154},[64,3496,2712],{"class":111},[64,3498,3400],{"class":107},[64,3500,175],{"class":111},[64,3502,178],{"class":107},[64,3504,140],{"class":111},[64,3506,183],{"class":107},[64,3508,140],{"class":111},[64,3510,188],{"class":107},[64,3512,191],{"class":111},[64,3514,1467],{"class":194},[64,3516,3517],{"class":111},")),\n",[64,3519,3520,3523,3525,3527,3529,3531,3533,3535,3537,3539],{"class":66,"line":160},[64,3521,3522],{"class":107},"          timer2_",[64,3524,175],{"class":111},[64,3526,178],{"class":107},[64,3528,140],{"class":111},[64,3530,183],{"class":107},[64,3532,140],{"class":111},[64,3534,188],{"class":107},[64,3536,191],{"class":111},[64,3538,1498],{"class":194},[64,3540,1879],{"class":111},[64,3542,3543],{"class":66,"line":201},[64,3544,632],{"class":111},[64,3546,3547,3549,3551,3553,3556,3558,3560],{"class":66,"line":206},[64,3548,637],{"class":107},[64,3550,212],{"class":111},[64,3552,215],{"class":70},[64,3554,3555],{"class":74}," \"TwoTimers 构造：注册 timer1 和 timer2\"",[64,3557,221],{"class":70},[64,3559,224],{"class":107},[64,3561,227],{"class":111},[64,3563,3564],{"class":66,"line":230},[64,3565,98],{"emptyLinePlaceholder":97},[64,3567,3568],{"class":66,"line":235},[64,3569,2763],{"class":124},[64,3571,3572,3575,3577,3579,3581,3583,3585,3587,3589,3592],{"class":66,"line":241},[64,3573,3574],{"class":111},"        timer1_.",[64,3576,815],{"class":107},[64,3578,191],{"class":111},[64,3580,178],{"class":107},[64,3582,140],{"class":111},[64,3584,824],{"class":107},[64,3586,191],{"class":111},[64,3588,609],{"class":70},[64,3590,3591],{"class":107},"TwoTimers",[64,3593,3594],{"class":111},"::on_timer1,\n",[64,3596,3597,3600],{"class":66,"line":253},[64,3598,3599],{"class":194},"                                     this",[64,3601,1993],{"class":111},[64,3603,3604,3607,3609,3611],{"class":66,"line":258},[64,3605,3606],{"class":107},"                                     std",[64,3608,140],{"class":111},[64,3610,834],{"class":107},[64,3612,837],{"class":111},[64,3614,3615],{"class":66,"line":276},[64,3616,98],{"emptyLinePlaceholder":97},[64,3618,3619,3622,3624,3626,3628,3630,3632,3634,3636,3638],{"class":66,"line":281},[64,3620,3621],{"class":111},"        timer2_.",[64,3623,815],{"class":107},[64,3625,191],{"class":111},[64,3627,178],{"class":107},[64,3629,140],{"class":111},[64,3631,824],{"class":107},[64,3633,191],{"class":111},[64,3635,609],{"class":70},[64,3637,3591],{"class":107},[64,3639,3640],{"class":111},"::on_timer2,\n",[64,3642,3643,3645],{"class":66,"line":293},[64,3644,3599],{"class":194},[64,3646,1993],{"class":111},[64,3648,3649,3651,3653,3655],{"class":66,"line":735},[64,3650,3606],{"class":107},[64,3652,140],{"class":111},[64,3654,834],{"class":107},[64,3656,837],{"class":111},[64,3658,3659],{"class":66,"line":740},[64,3660,673],{"class":111},[64,3662,3663],{"class":66,"line":745},[64,3664,98],{"emptyLinePlaceholder":97},[64,3666,3667],{"class":66,"line":776},[64,3668,2818],{"class":70},[64,3670,3671,3673,3676,3678,3680,3682,3684,3686,3688,3690,3692,3694],{"class":66,"line":781},[64,3672,2823],{"class":70},[64,3674,3675],{"class":107}," on_timer1",[64,3677,191],{"class":111},[64,3679,593],{"class":70},[64,3681,596],{"class":107},[64,3683,140],{"class":111},[64,3685,601],{"class":107},[64,3687,140],{"class":111},[64,3689,606],{"class":107},[64,3691,609],{"class":70},[64,3693,613],{"class":612},[64,3695,472],{"class":111},[64,3697,3698],{"class":66,"line":799},[64,3699,632],{"class":111},[64,3701,3702,3704],{"class":66,"line":804},[64,3703,2854],{"class":70},[64,3705,627],{"class":111},[64,3707,3708],{"class":66,"line":810},[64,3709,2861],{"class":111},[64,3711,3712,3714,3716,3718,3721,3723,3725,3727,3729,3731,3733],{"class":66,"line":840},[64,3713,2866],{"class":107},[64,3715,212],{"class":111},[64,3717,215],{"class":70},[64,3719,3720],{"class":74}," \"timer1 取消：\"",[64,3722,221],{"class":70},[64,3724,649],{"class":111},[64,3726,652],{"class":107},[64,3728,655],{"class":111},[64,3730,215],{"class":70},[64,3732,224],{"class":107},[64,3734,227],{"class":111},[64,3736,3737,3739],{"class":66,"line":845},[64,3738,2892],{"class":70},[64,3740,290],{"class":111},[64,3742,3743],{"class":66,"line":863},[64,3744,2899],{"class":111},[64,3746,3747],{"class":66,"line":881},[64,3748,98],{"emptyLinePlaceholder":97},[64,3750,3751,3753,3755,3757,3760,3762,3764],{"class":66,"line":886},[64,3752,637],{"class":107},[64,3754,212],{"class":111},[64,3756,215],{"class":70},[64,3758,3759],{"class":74}," \"timer1：1 秒到了\"",[64,3761,221],{"class":70},[64,3763,224],{"class":107},[64,3765,227],{"class":111},[64,3767,3768],{"class":66,"line":897},[64,3769,673],{"class":111},[64,3771,3772],{"class":66,"line":902},[64,3773,98],{"emptyLinePlaceholder":97},[64,3775,3776,3778,3781,3783,3785,3787,3789,3791,3793,3795,3797,3799],{"class":66,"line":920},[64,3777,2823],{"class":70},[64,3779,3780],{"class":107}," on_timer2",[64,3782,191],{"class":111},[64,3784,593],{"class":70},[64,3786,596],{"class":107},[64,3788,140],{"class":111},[64,3790,601],{"class":107},[64,3792,140],{"class":111},[64,3794,606],{"class":107},[64,3796,609],{"class":70},[64,3798,613],{"class":612},[64,3800,472],{"class":111},[64,3802,3803],{"class":66,"line":925},[64,3804,632],{"class":111},[64,3806,3807,3809],{"class":66,"line":934},[64,3808,2854],{"class":70},[64,3810,627],{"class":111},[64,3812,3813],{"class":66,"line":1658},[64,3814,2861],{"class":111},[64,3816,3817,3819,3821,3823,3826,3828,3830,3832,3834,3836,3838],{"class":66,"line":1663},[64,3818,2866],{"class":107},[64,3820,212],{"class":111},[64,3822,215],{"class":70},[64,3824,3825],{"class":74}," \"timer2 取消：\"",[64,3827,221],{"class":70},[64,3829,649],{"class":111},[64,3831,652],{"class":107},[64,3833,655],{"class":111},[64,3835,215],{"class":70},[64,3837,224],{"class":107},[64,3839,227],{"class":111},[64,3841,3842,3844],{"class":66,"line":1686},[64,3843,2892],{"class":70},[64,3845,290],{"class":111},[64,3847,3848],{"class":66,"line":1691},[64,3849,2899],{"class":111},[64,3851,3852],{"class":66,"line":1718},[64,3853,98],{"emptyLinePlaceholder":97},[64,3855,3856,3858,3860,3862,3865,3867,3869],{"class":66,"line":1723},[64,3857,637],{"class":107},[64,3859,212],{"class":111},[64,3861,215],{"class":70},[64,3863,3864],{"class":74}," \"timer2：3 秒到了\"",[64,3866,221],{"class":70},[64,3868,224],{"class":107},[64,3870,227],{"class":111},[64,3872,3873],{"class":66,"line":1732},[64,3874,673],{"class":111},[64,3876,3877],{"class":66,"line":2389},[64,3878,98],{"emptyLinePlaceholder":97},[64,3880,3881],{"class":66,"line":2398},[64,3882,2818],{"class":70},[64,3884,3885],{"class":66,"line":2406},[64,3886,157],{"class":124},[64,3888,3889,3891,3893,3895],{"class":66,"line":2411},[64,3890,137],{"class":107},[64,3892,140],{"class":111},[64,3894,143],{"class":107},[64,3896,3897],{"class":111},"::steady_timer timer1_;\n",[64,3899,3900,3902,3904,3906],{"class":66,"line":2420},[64,3901,137],{"class":107},[64,3903,140],{"class":111},[64,3905,143],{"class":107},[64,3907,3908],{"class":111},"::steady_timer timer2_;\n",[64,3910,3911],{"class":66,"line":2425},[64,3912,2952],{"class":111},[64,3914,3915],{"class":66,"line":2442},[64,3916,98],{"emptyLinePlaceholder":97},[64,3918,3919,3921,3923],{"class":66,"line":2447},[64,3920,104],{"class":70},[64,3922,108],{"class":107},[64,3924,112],{"class":111},[64,3926,3927],{"class":66,"line":2456},[64,3928,118],{"class":111},[64,3930,3932],{"class":66,"line":3931},57,[64,3933,125],{"class":124},[64,3935,3937],{"class":66,"line":3936},58,[64,3938,131],{"class":124},[64,3940,3942,3944,3946,3948],{"class":66,"line":3941},59,[64,3943,137],{"class":107},[64,3945,140],{"class":111},[64,3947,143],{"class":107},[64,3949,146],{"class":111},[64,3951,3953,3956,3959],{"class":66,"line":3952},60,[64,3954,3955],{"class":111},"    TwoTimers ",[64,3957,3958],{"class":107},"app",[64,3960,3001],{"class":111},[64,3962,3964],{"class":66,"line":3963},61,[64,3965,98],{"emptyLinePlaceholder":97},[64,3967,3969,3971,3973,3975,3977,3979,3981],{"class":66,"line":3968},62,[64,3970,209],{"class":107},[64,3972,212],{"class":111},[64,3974,215],{"class":70},[64,3976,1649],{"class":74},[64,3978,221],{"class":70},[64,3980,224],{"class":107},[64,3982,227],{"class":111},[64,3984,3986],{"class":66,"line":3985},63,[64,3987,98],{"emptyLinePlaceholder":97},[64,3989,3991,3993,3995],{"class":66,"line":3990},64,[64,3992,889],{"class":111},[64,3994,892],{"class":107},[64,3996,250],{"class":111},[64,3998,4000],{"class":66,"line":3999},65,[64,4001,98],{"emptyLinePlaceholder":97},[64,4003,4005,4007,4009,4011,4014,4016,4018],{"class":66,"line":4004},66,[64,4006,209],{"class":107},[64,4008,212],{"class":111},[64,4010,215],{"class":70},[64,4012,4013],{"class":74}," \"main：两个定时器都执行完，io.run() 返回\"",[64,4015,221],{"class":70},[64,4017,224],{"class":107},[64,4019,227],{"class":111},[64,4021,4023],{"class":66,"line":4022},67,[64,4024,98],{"emptyLinePlaceholder":97},[64,4026,4028,4030,4032],{"class":66,"line":4027},68,[64,4029,284],{"class":70},[64,4031,287],{"class":194},[64,4033,290],{"class":111},[64,4035,4037],{"class":66,"line":4036},69,[64,4038,296],{"class":111},[13,4040,4041,303],{},[300,4042,302],{},[45,4044,306],{"id":4045},"编译运行-5",[55,4047,4049],{"className":309,"code":4048,"language":311,"meta":60,"style":60},"g++ demo6_class_two_timers.cpp -o demo6_class_two_timers -std=c++17 -lboost_system -pthread\n./demo6_class_two_timers\n",[21,4050,4051,4069],{"__ignoreMap":60},[64,4052,4053,4055,4058,4060,4063,4065,4067],{"class":66,"line":67},[64,4054,318],{"class":107},[64,4056,4057],{"class":74}," demo6_class_two_timers.cpp",[64,4059,324],{"class":194},[64,4061,4062],{"class":74}," demo6_class_two_timers",[64,4064,330],{"class":194},[64,4066,333],{"class":194},[64,4068,336],{"class":194},[64,4070,4071],{"class":66,"line":78},[64,4072,4073],{"class":107},"./demo6_class_two_timers\n",[45,4075,344],{"id":4076},"运行输出与时间顺序-5",[13,4078,977],{},[55,4080,4083],{"className":4081,"code":4082,"language":350,"meta":60},[348],"TwoTimers 构造：注册 timer1 和 timer2\nmain：调用 io.run()\n",[21,4084,4082],{"__ignoreMap":60},[13,4086,2507],{},[55,4088,4091],{"className":4089,"code":4090,"language":350,"meta":60},[348],"timer1：1 秒到了\n",[21,4092,4090],{"__ignoreMap":60},[13,4094,4095],{},"约 3 秒后：",[55,4097,4100],{"className":4098,"code":4099,"language":350,"meta":60},[348],"timer2：3 秒到了\nmain：两个定时器都执行完，io.run() 返回\n",[21,4101,4099],{"__ignoreMap":60},[13,4103,364],{},[55,4105,4108],{"className":4106,"code":4107,"language":350,"meta":60},[348],"TwoTimers 构造：注册 timer1 和 timer2\nmain：调用 io.run()\ntimer1：1 秒到了\ntimer2：3 秒到了\nmain：两个定时器都执行完，io.run() 返回\n",[21,4109,4107],{"__ignoreMap":60},[45,4111,373],{"id":4112},"本示例需要注意的点-4",[13,4114,4115,1818,4117,4119],{},[21,4116,3400],{},[21,4118,3406],{}," 是两个异步任务，但本例仍然只有一个线程。",[13,4121,4122],{},"因为只有主线程调用了：",[55,4124,4125],{"className":57,"code":989,"language":59,"meta":60,"style":60},[21,4126,4127],{"__ignoreMap":60},[64,4128,4129,4131,4133],{"class":66,"line":67},[64,4130,996],{"class":111},[64,4132,892],{"class":107},[64,4134,250],{"class":111},[13,4136,4137],{},"所以两个回调都在主线程里执行，不会并行执行。",[33,4139],{},[36,4141,4143,4144],{"id":4142},"示例-7两个线程同时运行同一个-io_context","示例 7：两个线程同时运行同一个 ",[21,4145,447],{},[45,4147,47],{"id":4148},"程序目标-6",[13,4150,4151,4152,4154],{},"这次让两个线程都调用 ",[21,4153,527],{},"，观察回调可能由不同线程执行。",[13,4156,4157],{},"这个例子用于理解官方 Timer.5 那类程序：",[55,4159,4162],{"className":4160,"code":4161,"language":350,"meta":60},[348],"多个线程 run 同一个 io_context\n回调函数可能分配给任意一个正在 run 的线程执行\n",[21,4163,4161],{"__ignoreMap":60},[45,4165,53],{"id":4166},"完整代码-6",[55,4168,4170],{"className":57,"code":4169,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cstring>\n#include \u003Cthread>\n\nvoid print_timer(const boost::system::error_code& ec, const std::string& name)\n{\n    if (ec)\n    {\n        std::cout \u003C\u003C name \u003C\u003C \" 取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n        return;\n    }\n\n    std::cout \u003C\u003C name \u003C\u003C \" 回调执行，线程 id = \"\n              \u003C\u003C std::this_thread::get_id() \u003C\u003C std::endl;\n}\n\nvoid run_io(boost::asio::io_context* io, const std::string& thread_name)\n{\n    std::cout \u003C\u003C thread_name \u003C\u003C \" 开始调用 io.run()，线程 id = \"\n              \u003C\u003C std::this_thread::get_id() \u003C\u003C std::endl;\n\n    io->run();\n\n    std::cout \u003C\u003C thread_name \u003C\u003C \" 的 io.run() 返回\" \u003C\u003C std::endl;\n}\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer1(io, std::chrono::seconds(1));\n    boost::asio::steady_timer timer2(io, std::chrono::seconds(1));\n\n    // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n    timer1.async_wait(std::bind(print_timer,\n                                std::placeholders::_1,\n                                std::string(\"timer1\")));\n\n    timer2.async_wait(std::bind(print_timer,\n                                std::placeholders::_1,\n                                std::string(\"timer2\")));\n\n    std::thread t1(std::bind(run_io, &io, std::string(\"线程1\")));\n    std::thread t2(std::bind(run_io, &io, std::string(\"线程2\")));\n\n    t1.join();\n    t2.join();\n\n    std::cout \u003C\u003C \"main：两个线程都结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,4171,4172,4178,4184,4190,4196,4202,4208,4215,4219,4260,4264,4270,4274,4303,4309,4313,4317,4332,4357,4361,4365,4405,4409,4425,4447,4451,4460,4464,4485,4489,4493,4501,4505,4509,4513,4523,4527,4531,4561,4591,4595,4599,4616,4626,4640,4644,4660,4670,4684,4688,4727,4763,4767,4777,4786,4790,4807,4811,4819],{"__ignoreMap":60},[64,4173,4174,4176],{"class":66,"line":67},[64,4175,71],{"class":70},[64,4177,75],{"class":74},[64,4179,4180,4182],{"class":66,"line":78},[64,4181,71],{"class":70},[64,4183,558],{"class":74},[64,4185,4186,4188],{"class":66,"line":86},[64,4187,71],{"class":70},[64,4189,83],{"class":74},[64,4191,4192,4194],{"class":66,"line":94},[64,4193,71],{"class":70},[64,4195,571],{"class":74},[64,4197,4198,4200],{"class":66,"line":101},[64,4199,71],{"class":70},[64,4201,91],{"class":74},[64,4203,4204,4206],{"class":66,"line":115},[64,4205,71],{"class":70},[64,4207,1266],{"class":74},[64,4209,4210,4212],{"class":66,"line":121},[64,4211,71],{"class":70},[64,4213,4214],{"class":74}," \u003Cthread>\n",[64,4216,4217],{"class":66,"line":128},[64,4218,98],{"emptyLinePlaceholder":97},[64,4220,4221,4223,4226,4228,4230,4232,4234,4236,4238,4240,4242,4244,4246,4248,4250,4252,4254,4256,4258],{"class":66,"line":134},[64,4222,490],{"class":70},[64,4224,4225],{"class":107}," print_timer",[64,4227,191],{"class":111},[64,4229,593],{"class":70},[64,4231,596],{"class":107},[64,4233,140],{"class":111},[64,4235,601],{"class":107},[64,4237,140],{"class":111},[64,4239,606],{"class":107},[64,4241,609],{"class":70},[64,4243,613],{"class":612},[64,4245,1297],{"class":111},[64,4247,593],{"class":70},[64,4249,224],{"class":107},[64,4251,140],{"class":111},[64,4253,1306],{"class":107},[64,4255,609],{"class":70},[64,4257,1311],{"class":612},[64,4259,472],{"class":111},[64,4261,4262],{"class":66,"line":149},[64,4263,118],{"class":111},[64,4265,4266,4268],{"class":66,"line":154},[64,4267,624],{"class":70},[64,4269,627],{"class":111},[64,4271,4272],{"class":66,"line":160},[64,4273,632],{"class":111},[64,4275,4276,4278,4280,4282,4284,4286,4289,4291,4293,4295,4297,4299,4301],{"class":66,"line":201},[64,4277,637],{"class":107},[64,4279,212],{"class":111},[64,4281,215],{"class":70},[64,4283,1338],{"class":111},[64,4285,215],{"class":70},[64,4287,4288],{"class":74}," \" 取消：\"",[64,4290,221],{"class":70},[64,4292,649],{"class":111},[64,4294,652],{"class":107},[64,4296,655],{"class":111},[64,4298,215],{"class":70},[64,4300,224],{"class":107},[64,4302,227],{"class":111},[64,4304,4305,4307],{"class":66,"line":206},[64,4306,666],{"class":70},[64,4308,290],{"class":111},[64,4310,4311],{"class":66,"line":230},[64,4312,673],{"class":111},[64,4314,4315],{"class":66,"line":235},[64,4316,98],{"emptyLinePlaceholder":97},[64,4318,4319,4321,4323,4325,4327,4329],{"class":66,"line":241},[64,4320,209],{"class":107},[64,4322,212],{"class":111},[64,4324,215],{"class":70},[64,4326,1338],{"class":111},[64,4328,215],{"class":70},[64,4330,4331],{"class":74}," \" 回调执行，线程 id = \"\n",[64,4333,4334,4337,4339,4341,4344,4346,4349,4351,4353,4355],{"class":66,"line":253},[64,4335,4336],{"class":70},"              \u003C\u003C",[64,4338,224],{"class":107},[64,4340,140],{"class":111},[64,4342,4343],{"class":107},"this_thread",[64,4345,140],{"class":111},[64,4347,4348],{"class":107},"get_id",[64,4350,655],{"class":111},[64,4352,215],{"class":70},[64,4354,224],{"class":107},[64,4356,227],{"class":111},[64,4358,4359],{"class":66,"line":258},[64,4360,296],{"class":111},[64,4362,4363],{"class":66,"line":276},[64,4364,98],{"emptyLinePlaceholder":97},[64,4366,4367,4369,4372,4374,4376,4378,4380,4382,4384,4386,4388,4390,4392,4394,4396,4398,4400,4403],{"class":66,"line":281},[64,4368,490],{"class":70},[64,4370,4371],{"class":107}," run_io",[64,4373,191],{"class":111},[64,4375,2692],{"class":107},[64,4377,140],{"class":111},[64,4379,143],{"class":107},[64,4381,140],{"class":111},[64,4383,447],{"class":107},[64,4385,2010],{"class":70},[64,4387,2705],{"class":612},[64,4389,1297],{"class":111},[64,4391,593],{"class":70},[64,4393,224],{"class":107},[64,4395,140],{"class":111},[64,4397,1306],{"class":107},[64,4399,609],{"class":70},[64,4401,4402],{"class":612}," thread_name",[64,4404,472],{"class":111},[64,4406,4407],{"class":66,"line":293},[64,4408,118],{"class":111},[64,4410,4411,4413,4415,4417,4420,4422],{"class":66,"line":735},[64,4412,209],{"class":107},[64,4414,212],{"class":111},[64,4416,215],{"class":70},[64,4418,4419],{"class":111}," thread_name ",[64,4421,215],{"class":70},[64,4423,4424],{"class":74}," \" 开始调用 io.run()，线程 id = \"\n",[64,4426,4427,4429,4431,4433,4435,4437,4439,4441,4443,4445],{"class":66,"line":740},[64,4428,4336],{"class":70},[64,4430,224],{"class":107},[64,4432,140],{"class":111},[64,4434,4343],{"class":107},[64,4436,140],{"class":111},[64,4438,4348],{"class":107},[64,4440,655],{"class":111},[64,4442,215],{"class":70},[64,4444,224],{"class":107},[64,4446,227],{"class":111},[64,4448,4449],{"class":66,"line":745},[64,4450,98],{"emptyLinePlaceholder":97},[64,4452,4453,4456,4458],{"class":66,"line":776},[64,4454,4455],{"class":111},"    io->",[64,4457,892],{"class":107},[64,4459,250],{"class":111},[64,4461,4462],{"class":66,"line":781},[64,4463,98],{"emptyLinePlaceholder":97},[64,4465,4466,4468,4470,4472,4474,4476,4479,4481,4483],{"class":66,"line":799},[64,4467,209],{"class":107},[64,4469,212],{"class":111},[64,4471,215],{"class":70},[64,4473,4419],{"class":111},[64,4475,215],{"class":70},[64,4477,4478],{"class":74}," \" 的 io.run() 返回\"",[64,4480,221],{"class":70},[64,4482,224],{"class":107},[64,4484,227],{"class":111},[64,4486,4487],{"class":66,"line":804},[64,4488,296],{"class":111},[64,4490,4491],{"class":66,"line":810},[64,4492,98],{"emptyLinePlaceholder":97},[64,4494,4495,4497,4499],{"class":66,"line":840},[64,4496,104],{"class":70},[64,4498,108],{"class":107},[64,4500,112],{"class":111},[64,4502,4503],{"class":66,"line":845},[64,4504,118],{"class":111},[64,4506,4507],{"class":66,"line":863},[64,4508,125],{"class":124},[64,4510,4511],{"class":66,"line":881},[64,4512,131],{"class":124},[64,4514,4515,4517,4519,4521],{"class":66,"line":886},[64,4516,137],{"class":107},[64,4518,140],{"class":111},[64,4520,143],{"class":107},[64,4522,146],{"class":111},[64,4524,4525],{"class":66,"line":897},[64,4526,98],{"emptyLinePlaceholder":97},[64,4528,4529],{"class":66,"line":902},[64,4530,157],{"class":124},[64,4532,4533,4535,4537,4539,4541,4543,4545,4547,4549,4551,4553,4555,4557,4559],{"class":66,"line":920},[64,4534,137],{"class":107},[64,4536,140],{"class":111},[64,4538,143],{"class":107},[64,4540,169],{"class":111},[64,4542,1203],{"class":107},[64,4544,175],{"class":111},[64,4546,178],{"class":107},[64,4548,140],{"class":111},[64,4550,183],{"class":107},[64,4552,140],{"class":111},[64,4554,188],{"class":107},[64,4556,191],{"class":111},[64,4558,1467],{"class":194},[64,4560,198],{"class":111},[64,4562,4563,4565,4567,4569,4571,4573,4575,4577,4579,4581,4583,4585,4587,4589],{"class":66,"line":925},[64,4564,137],{"class":107},[64,4566,140],{"class":111},[64,4568,143],{"class":107},[64,4570,169],{"class":111},[64,4572,1209],{"class":107},[64,4574,175],{"class":111},[64,4576,178],{"class":107},[64,4578,140],{"class":111},[64,4580,183],{"class":107},[64,4582,140],{"class":111},[64,4584,188],{"class":107},[64,4586,191],{"class":111},[64,4588,1467],{"class":194},[64,4590,198],{"class":111},[64,4592,4593],{"class":66,"line":934},[64,4594,98],{"emptyLinePlaceholder":97},[64,4596,4597],{"class":66,"line":1658},[64,4598,807],{"class":124},[64,4600,4601,4603,4605,4607,4609,4611,4613],{"class":66,"line":1663},[64,4602,1530],{"class":111},[64,4604,815],{"class":107},[64,4606,191],{"class":111},[64,4608,178],{"class":107},[64,4610,140],{"class":111},[64,4612,824],{"class":107},[64,4614,4615],{"class":111},"(print_timer,\n",[64,4617,4618,4620,4622,4624],{"class":66,"line":1686},[64,4619,1548],{"class":107},[64,4621,140],{"class":111},[64,4623,834],{"class":107},[64,4625,1555],{"class":111},[64,4627,4628,4630,4632,4634,4636,4638],{"class":66,"line":1691},[64,4629,1548],{"class":107},[64,4631,140],{"class":111},[64,4633,1306],{"class":107},[64,4635,191],{"class":111},[64,4637,1568],{"class":74},[64,4639,1571],{"class":111},[64,4641,4642],{"class":66,"line":1718},[64,4643,98],{"emptyLinePlaceholder":97},[64,4645,4646,4648,4650,4652,4654,4656,4658],{"class":66,"line":1723},[64,4647,1597],{"class":111},[64,4649,815],{"class":107},[64,4651,191],{"class":111},[64,4653,178],{"class":107},[64,4655,140],{"class":111},[64,4657,824],{"class":107},[64,4659,4615],{"class":111},[64,4661,4662,4664,4666,4668],{"class":66,"line":1732},[64,4663,1548],{"class":107},[64,4665,140],{"class":111},[64,4667,834],{"class":107},[64,4669,1555],{"class":111},[64,4671,4672,4674,4676,4678,4680,4682],{"class":66,"line":2389},[64,4673,1548],{"class":107},[64,4675,140],{"class":111},[64,4677,1306],{"class":107},[64,4679,191],{"class":111},[64,4681,1632],{"class":74},[64,4683,1571],{"class":111},[64,4685,4686],{"class":66,"line":2398},[64,4687,98],{"emptyLinePlaceholder":97},[64,4689,4690,4692,4695,4698,4700,4702,4704,4706,4709,4711,4714,4716,4718,4720,4722,4725],{"class":66,"line":2406},[64,4691,209],{"class":107},[64,4693,4694],{"class":111},"::thread ",[64,4696,4697],{"class":107},"t1",[64,4699,191],{"class":111},[64,4701,178],{"class":107},[64,4703,140],{"class":111},[64,4705,824],{"class":107},[64,4707,4708],{"class":111},"(run_io, ",[64,4710,609],{"class":70},[64,4712,4713],{"class":111},"io, ",[64,4715,178],{"class":107},[64,4717,140],{"class":111},[64,4719,1306],{"class":107},[64,4721,191],{"class":111},[64,4723,4724],{"class":74},"\"线程1\"",[64,4726,1571],{"class":111},[64,4728,4729,4731,4733,4736,4738,4740,4742,4744,4746,4748,4750,4752,4754,4756,4758,4761],{"class":66,"line":2411},[64,4730,209],{"class":107},[64,4732,4694],{"class":111},[64,4734,4735],{"class":107},"t2",[64,4737,191],{"class":111},[64,4739,178],{"class":107},[64,4741,140],{"class":111},[64,4743,824],{"class":107},[64,4745,4708],{"class":111},[64,4747,609],{"class":70},[64,4749,4713],{"class":111},[64,4751,178],{"class":107},[64,4753,140],{"class":111},[64,4755,1306],{"class":107},[64,4757,191],{"class":111},[64,4759,4760],{"class":74},"\"线程2\"",[64,4762,1571],{"class":111},[64,4764,4765],{"class":66,"line":2420},[64,4766,98],{"emptyLinePlaceholder":97},[64,4768,4769,4772,4775],{"class":66,"line":2425},[64,4770,4771],{"class":111},"    t1.",[64,4773,4774],{"class":107},"join",[64,4776,250],{"class":111},[64,4778,4779,4782,4784],{"class":66,"line":2442},[64,4780,4781],{"class":111},"    t2.",[64,4783,4774],{"class":107},[64,4785,250],{"class":111},[64,4787,4788],{"class":66,"line":2447},[64,4789,98],{"emptyLinePlaceholder":97},[64,4791,4792,4794,4796,4798,4801,4803,4805],{"class":66,"line":2456},[64,4793,209],{"class":107},[64,4795,212],{"class":111},[64,4797,215],{"class":70},[64,4799,4800],{"class":74}," \"main：两个线程都结束\"",[64,4802,221],{"class":70},[64,4804,224],{"class":107},[64,4806,227],{"class":111},[64,4808,4809],{"class":66,"line":3931},[64,4810,98],{"emptyLinePlaceholder":97},[64,4812,4813,4815,4817],{"class":66,"line":3936},[64,4814,284],{"class":70},[64,4816,287],{"class":194},[64,4818,290],{"class":111},[64,4820,4821],{"class":66,"line":3941},[64,4822,296],{"class":111},[13,4824,4825,303],{},[300,4826,302],{},[45,4828,306],{"id":4829},"编译运行-6",[55,4831,4833],{"className":309,"code":4832,"language":311,"meta":60,"style":60},"g++ demo7_two_threads.cpp -o demo7_two_threads -std=c++17 -lboost_system -pthread\n./demo7_two_threads\n",[21,4834,4835,4853],{"__ignoreMap":60},[64,4836,4837,4839,4842,4844,4847,4849,4851],{"class":66,"line":67},[64,4838,318],{"class":107},[64,4840,4841],{"class":74}," demo7_two_threads.cpp",[64,4843,324],{"class":194},[64,4845,4846],{"class":74}," demo7_two_threads",[64,4848,330],{"class":194},[64,4850,333],{"class":194},[64,4852,336],{"class":194},[64,4854,4855],{"class":66,"line":78},[64,4856,4857],{"class":107},"./demo7_two_threads\n",[45,4859,344],{"id":4860},"运行输出与时间顺序-6",[13,4862,4863],{},"程序启动后两个线程几乎立刻输出：",[55,4865,4868],{"className":4866,"code":4867,"language":350,"meta":60},[348],"线程1 开始调用 io.run()，线程 id = 140000000000001\n线程2 开始调用 io.run()，线程 id = 140000000000002\n",[21,4869,4867],{"__ignoreMap":60},[13,4871,4872],{},"约 1 秒后，两个 timer 都到期，输出可能类似：",[55,4874,4877],{"className":4875,"code":4876,"language":350,"meta":60},[348],"timer1 回调执行，线程 id = 140000000000001\ntimer2 回调执行，线程 id = 140000000000002\n线程1 的 io.run() 返回\n线程2 的 io.run() 返回\nmain：两个线程都结束\n",[21,4878,4876],{"__ignoreMap":60},[13,4880,4881],{},"也可能两个回调都被同一个线程执行。线程调度不保证固定。",[45,4883,373],{"id":4884},"本示例需要注意的点-5",[13,4886,4887],{},"这个示例的重点是：",[55,4889,4892],{"className":4890,"code":4891,"language":350,"meta":60},[348],"谁调用 io.run()，谁就有可能执行回调函数。\n",[21,4893,4891],{"__ignoreMap":60},[13,4895,4896,4897,4899,4900,4902],{},"不是 ",[21,4898,1203],{}," 固定属于线程 1，",[21,4901,1209],{}," 固定属于线程 2。",[45,4904,4906,4909,4910],{"id":4905},"stdthread-里的-stdbind",[21,4907,4908],{},"std::thread"," 里的 ",[21,4911,30],{},[13,4913,1842],{},[55,4915,4917],{"className":57,"code":4916,"language":59,"meta":60,"style":60},"std::thread t1(std::bind(run_io, &io, std::string(\"线程1\")));\n",[21,4918,4919],{"__ignoreMap":60},[64,4920,4921,4923,4925,4928,4931,4933,4935,4937,4939,4941,4943,4945,4947,4949,4951,4953,4955],{"class":66,"line":67},[64,4922,178],{"class":107},[64,4924,140],{"class":111},[64,4926,4927],{"class":107},"thread",[64,4929,4930],{"class":107}," t1",[64,4932,191],{"class":111},[64,4934,178],{"class":107},[64,4936,140],{"class":111},[64,4938,824],{"class":107},[64,4940,4708],{"class":111},[64,4942,609],{"class":70},[64,4944,4713],{"class":111},[64,4946,178],{"class":107},[64,4948,140],{"class":111},[64,4950,1306],{"class":107},[64,4952,191],{"class":111},[64,4954,4724],{"class":74},[64,4956,1571],{"class":111},[13,4958,4959],{},"意思是创建一个线程，在新线程里执行：",[55,4961,4963],{"className":57,"code":4962,"language":59,"meta":60,"style":60},"run_io(&io, \"线程1\");\n",[21,4964,4965],{"__ignoreMap":60},[64,4966,4967,4970,4972,4974,4976,4978],{"class":66,"line":67},[64,4968,4969],{"class":107},"run_io",[64,4971,191],{"class":111},[64,4973,609],{"class":70},[64,4975,4713],{"class":111},[64,4977,4724],{"class":74},[64,4979,4980],{"class":111},");\n",[13,4982,4983],{},"这里也没有使用 lambda。",[33,4985],{},[36,4987,4989,4990,4993],{"id":4988},"示例-8多线程下使用-strand-避免回调并发","示例 8：多线程下使用 ",[21,4991,4992],{},"strand"," 避免回调并发",[45,4995,47],{"id":4996},"程序目标-7",[13,4998,4999,5000,5003,5004,5006,5007,5009],{},"如果多个线程同时 ",[21,5001,5002],{},"run()"," 一个 ",[21,5005,447],{},"，不同回调可能同时执行。",[17,5008],{},"\n如果这些回调都要修改同一个成员变量，就可能出现数据竞争。",[13,5011,5012,5014],{},[21,5013,4992],{}," 的作用是：",[55,5016,5019],{"className":5017,"code":5018,"language":350,"meta":60},[348],"保证绑定到同一个 strand 上的 handler 不会并发执行。\n",[21,5020,5018],{"__ignoreMap":60},[45,5022,53],{"id":5023},"完整代码-7",[55,5025,5027],{"className":57,"code":5026,"language":59,"meta":60,"style":60},"#include \u003Cboost/asio.hpp>\n#include \u003Cboost/system/error_code.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Ciostream>\n#include \u003Cthread>\n\nclass StrandCounter\n{\npublic:\n    explicit StrandCounter(boost::asio::io_context& io)\n        : strand_(boost::asio::make_strand(io)),\n          timer1_(io, std::chrono::seconds(1)),\n          timer2_(io, std::chrono::seconds(1)),\n          count_(0)\n    {\n        // 注册异步等待：这一行不会阻塞，回调会在定时器到期后执行。\n        timer1_.async_wait(\n            boost::asio::bind_executor(\n                strand_,\n                std::bind(&StrandCounter::on_timer,\n                          this,\n                          std::placeholders::_1,\n                          1)));\n\n        timer2_.async_wait(\n            boost::asio::bind_executor(\n                strand_,\n                std::bind(&StrandCounter::on_timer,\n                          this,\n                          std::placeholders::_1,\n                          2)));\n    }\n\nprivate:\n    void on_timer(const boost::system::error_code& ec, int id)\n    {\n        if (ec)\n        {\n            std::cout \u003C\u003C \"timer\" \u003C\u003C id \u003C\u003C \" 取消：\" \u003C\u003C ec.message() \u003C\u003C std::endl;\n            return;\n        }\n\n        ++count_;\n\n        std::cout \u003C\u003C \"timer\" \u003C\u003C id \u003C\u003C \" 回调执行，count = \" \u003C\u003C count_\n                  \u003C\u003C \"，线程 id = \" \u003C\u003C std::this_thread::get_id() \u003C\u003C std::endl;\n    }\n\nprivate:\n    boost::asio::strand\u003Cboost::asio::io_context::executor_type> strand_;\n    // 创建定时器，并设置到期时间。\n    boost::asio::steady_timer timer1_;\n    boost::asio::steady_timer timer2_;\n    int count_;\n};\n\nvoid run_io(boost::asio::io_context* io, const std::string& name)\n{\n    std::cout \u003C\u003C name \u003C\u003C \" 开始 run，线程 id = \"\n              \u003C\u003C std::this_thread::get_id() \u003C\u003C std::endl;\n\n    io->run();\n\n    std::cout \u003C\u003C name \u003C\u003C \" run 返回\" \u003C\u003C std::endl;\n}\n\nint main()\n{\n    // 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    // io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n    StrandCounter counter(io);\n\n    std::thread t1(std::bind(run_io, &io, std::string(\"线程1\")));\n    std::thread t2(std::bind(run_io, &io, std::string(\"线程2\")));\n\n    t1.join();\n    t2.join();\n\n    std::cout \u003C\u003C \"main：结束\" \u003C\u003C std::endl;\n\n    return 0;\n}\n",[21,5028,5029,5035,5041,5047,5053,5059,5065,5069,5076,5080,5084,5109,5132,5155,5177,5189,5193,5197,5206,5222,5227,5245,5252,5263,5270,5274,5282,5296,5300,5316,5322,5332,5339,5343,5347,5351,5384,5388,5394,5398,5432,5438,5442,5446,5454,5458,5482,5510,5514,5518,5522,5554,5558,5568,5578,5585,5589,5593,5631,5635,5650,5672,5676,5684,5688,5709,5713,5717,5725,5729,5734,5739,5750,5761,5766,5801,5836,5841,5850,5859,5864,5882,5887,5896],{"__ignoreMap":60},[64,5030,5031,5033],{"class":66,"line":67},[64,5032,71],{"class":70},[64,5034,75],{"class":74},[64,5036,5037,5039],{"class":66,"line":78},[64,5038,71],{"class":70},[64,5040,558],{"class":74},[64,5042,5043,5045],{"class":66,"line":86},[64,5044,71],{"class":70},[64,5046,83],{"class":74},[64,5048,5049,5051],{"class":66,"line":94},[64,5050,71],{"class":70},[64,5052,571],{"class":74},[64,5054,5055,5057],{"class":66,"line":101},[64,5056,71],{"class":70},[64,5058,91],{"class":74},[64,5060,5061,5063],{"class":66,"line":115},[64,5062,71],{"class":70},[64,5064,4214],{"class":74},[64,5066,5067],{"class":66,"line":121},[64,5068,98],{"emptyLinePlaceholder":97},[64,5070,5071,5073],{"class":66,"line":128},[64,5072,2667],{"class":70},[64,5074,5075],{"class":107}," StrandCounter\n",[64,5077,5078],{"class":66,"line":134},[64,5079,118],{"class":111},[64,5081,5082],{"class":66,"line":149},[64,5083,2679],{"class":70},[64,5085,5086,5088,5091,5093,5095,5097,5099,5101,5103,5105,5107],{"class":66,"line":154},[64,5087,2684],{"class":70},[64,5089,5090],{"class":107}," StrandCounter",[64,5092,191],{"class":111},[64,5094,2692],{"class":107},[64,5096,140],{"class":111},[64,5098,143],{"class":107},[64,5100,140],{"class":111},[64,5102,447],{"class":107},[64,5104,609],{"class":70},[64,5106,2705],{"class":612},[64,5108,472],{"class":111},[64,5110,5111,5113,5116,5118,5120,5122,5124,5126,5129],{"class":66,"line":160},[64,5112,2712],{"class":111},[64,5114,5115],{"class":107},"strand_",[64,5117,191],{"class":111},[64,5119,2692],{"class":107},[64,5121,140],{"class":111},[64,5123,143],{"class":107},[64,5125,140],{"class":111},[64,5127,5128],{"class":107},"make_strand",[64,5130,5131],{"class":111},"(io)),\n",[64,5133,5134,5137,5139,5141,5143,5145,5147,5149,5151,5153],{"class":66,"line":201},[64,5135,5136],{"class":107},"          timer1_",[64,5138,175],{"class":111},[64,5140,178],{"class":107},[64,5142,140],{"class":111},[64,5144,183],{"class":107},[64,5146,140],{"class":111},[64,5148,188],{"class":107},[64,5150,191],{"class":111},[64,5152,1467],{"class":194},[64,5154,3517],{"class":111},[64,5156,5157,5159,5161,5163,5165,5167,5169,5171,5173,5175],{"class":66,"line":206},[64,5158,3522],{"class":107},[64,5160,175],{"class":111},[64,5162,178],{"class":107},[64,5164,140],{"class":111},[64,5166,183],{"class":107},[64,5168,140],{"class":111},[64,5170,188],{"class":107},[64,5172,191],{"class":111},[64,5174,1467],{"class":194},[64,5176,3517],{"class":111},[64,5178,5179,5182,5184,5187],{"class":66,"line":230},[64,5180,5181],{"class":107},"          count_",[64,5183,191],{"class":111},[64,5185,5186],{"class":194},"0",[64,5188,472],{"class":111},[64,5190,5191],{"class":66,"line":235},[64,5192,632],{"class":111},[64,5194,5195],{"class":66,"line":241},[64,5196,2763],{"class":124},[64,5198,5199,5201,5203],{"class":66,"line":253},[64,5200,3574],{"class":111},[64,5202,815],{"class":107},[64,5204,5205],{"class":111},"(\n",[64,5207,5208,5211,5213,5215,5217,5220],{"class":66,"line":258},[64,5209,5210],{"class":107},"            boost",[64,5212,140],{"class":111},[64,5214,143],{"class":107},[64,5216,140],{"class":111},[64,5218,5219],{"class":107},"bind_executor",[64,5221,5205],{"class":111},[64,5223,5224],{"class":66,"line":276},[64,5225,5226],{"class":111},"                strand_,\n",[64,5228,5229,5232,5234,5236,5238,5240,5243],{"class":66,"line":281},[64,5230,5231],{"class":107},"                std",[64,5233,140],{"class":111},[64,5235,824],{"class":107},[64,5237,191],{"class":111},[64,5239,609],{"class":70},[64,5241,5242],{"class":107},"StrandCounter",[64,5244,2788],{"class":111},[64,5246,5247,5250],{"class":66,"line":293},[64,5248,5249],{"class":194},"                          this",[64,5251,1993],{"class":111},[64,5253,5254,5257,5259,5261],{"class":66,"line":735},[64,5255,5256],{"class":107},"                          std",[64,5258,140],{"class":111},[64,5260,834],{"class":107},[64,5262,1555],{"class":111},[64,5264,5265,5268],{"class":66,"line":740},[64,5266,5267],{"class":194},"                          1",[64,5269,1571],{"class":111},[64,5271,5272],{"class":66,"line":745},[64,5273,98],{"emptyLinePlaceholder":97},[64,5275,5276,5278,5280],{"class":66,"line":776},[64,5277,3621],{"class":111},[64,5279,815],{"class":107},[64,5281,5205],{"class":111},[64,5283,5284,5286,5288,5290,5292,5294],{"class":66,"line":781},[64,5285,5210],{"class":107},[64,5287,140],{"class":111},[64,5289,143],{"class":107},[64,5291,140],{"class":111},[64,5293,5219],{"class":107},[64,5295,5205],{"class":111},[64,5297,5298],{"class":66,"line":799},[64,5299,5226],{"class":111},[64,5301,5302,5304,5306,5308,5310,5312,5314],{"class":66,"line":804},[64,5303,5231],{"class":107},[64,5305,140],{"class":111},[64,5307,824],{"class":107},[64,5309,191],{"class":111},[64,5311,609],{"class":70},[64,5313,5242],{"class":107},[64,5315,2788],{"class":111},[64,5317,5318,5320],{"class":66,"line":810},[64,5319,5249],{"class":194},[64,5321,1993],{"class":111},[64,5323,5324,5326,5328,5330],{"class":66,"line":840},[64,5325,5256],{"class":107},[64,5327,140],{"class":111},[64,5329,834],{"class":107},[64,5331,1555],{"class":111},[64,5333,5334,5337],{"class":66,"line":845},[64,5335,5336],{"class":194},"                          2",[64,5338,1571],{"class":111},[64,5340,5341],{"class":66,"line":863},[64,5342,673],{"class":111},[64,5344,5345],{"class":66,"line":881},[64,5346,98],{"emptyLinePlaceholder":97},[64,5348,5349],{"class":66,"line":886},[64,5350,2818],{"class":70},[64,5352,5353,5355,5357,5359,5361,5363,5365,5367,5369,5371,5373,5375,5377,5379,5382],{"class":66,"line":897},[64,5354,2823],{"class":70},[64,5356,588],{"class":107},[64,5358,191],{"class":111},[64,5360,593],{"class":70},[64,5362,596],{"class":107},[64,5364,140],{"class":111},[64,5366,601],{"class":107},[64,5368,140],{"class":111},[64,5370,606],{"class":107},[64,5372,609],{"class":70},[64,5374,613],{"class":612},[64,5376,1297],{"class":111},[64,5378,104],{"class":70},[64,5380,5381],{"class":612}," id",[64,5383,472],{"class":111},[64,5385,5386],{"class":66,"line":902},[64,5387,632],{"class":111},[64,5389,5390,5392],{"class":66,"line":920},[64,5391,2854],{"class":70},[64,5393,627],{"class":111},[64,5395,5396],{"class":66,"line":925},[64,5397,2861],{"class":111},[64,5399,5400,5402,5404,5406,5409,5411,5414,5416,5418,5420,5422,5424,5426,5428,5430],{"class":66,"line":934},[64,5401,2866],{"class":107},[64,5403,212],{"class":111},[64,5405,215],{"class":70},[64,5407,5408],{"class":74}," \"timer\"",[64,5410,221],{"class":70},[64,5412,5413],{"class":111}," id ",[64,5415,215],{"class":70},[64,5417,4288],{"class":74},[64,5419,221],{"class":70},[64,5421,649],{"class":111},[64,5423,652],{"class":107},[64,5425,655],{"class":111},[64,5427,215],{"class":70},[64,5429,224],{"class":107},[64,5431,227],{"class":111},[64,5433,5434,5436],{"class":66,"line":1658},[64,5435,2892],{"class":70},[64,5437,290],{"class":111},[64,5439,5440],{"class":66,"line":1663},[64,5441,2899],{"class":111},[64,5443,5444],{"class":66,"line":1686},[64,5445,98],{"emptyLinePlaceholder":97},[64,5447,5448,5451],{"class":66,"line":1691},[64,5449,5450],{"class":70},"        ++",[64,5452,5453],{"class":111},"count_;\n",[64,5455,5456],{"class":66,"line":1718},[64,5457,98],{"emptyLinePlaceholder":97},[64,5459,5460,5462,5464,5466,5468,5470,5472,5474,5477,5479],{"class":66,"line":1723},[64,5461,637],{"class":107},[64,5463,212],{"class":111},[64,5465,215],{"class":70},[64,5467,5408],{"class":74},[64,5469,221],{"class":70},[64,5471,5413],{"class":111},[64,5473,215],{"class":70},[64,5475,5476],{"class":74}," \" 回调执行，count = \"",[64,5478,221],{"class":70},[64,5480,5481],{"class":111}," count_\n",[64,5483,5484,5487,5490,5492,5494,5496,5498,5500,5502,5504,5506,5508],{"class":66,"line":1732},[64,5485,5486],{"class":70},"                  \u003C\u003C",[64,5488,5489],{"class":74}," \"，线程 id = \"",[64,5491,221],{"class":70},[64,5493,224],{"class":107},[64,5495,140],{"class":111},[64,5497,4343],{"class":107},[64,5499,140],{"class":111},[64,5501,4348],{"class":107},[64,5503,655],{"class":111},[64,5505,215],{"class":70},[64,5507,224],{"class":107},[64,5509,227],{"class":111},[64,5511,5512],{"class":66,"line":2389},[64,5513,673],{"class":111},[64,5515,5516],{"class":66,"line":2398},[64,5517,98],{"emptyLinePlaceholder":97},[64,5519,5520],{"class":66,"line":2406},[64,5521,2818],{"class":70},[64,5523,5524,5526,5528,5530,5533,5535,5537,5539,5541,5543,5545,5548,5551],{"class":66,"line":2411},[64,5525,137],{"class":107},[64,5527,140],{"class":111},[64,5529,143],{"class":107},[64,5531,5532],{"class":111},"::strand",[64,5534,2138],{"class":70},[64,5536,2692],{"class":107},[64,5538,140],{"class":111},[64,5540,143],{"class":107},[64,5542,140],{"class":111},[64,5544,447],{"class":107},[64,5546,5547],{"class":111},"::executor_type",[64,5549,5550],{"class":70},">",[64,5552,5553],{"class":111}," strand_;\n",[64,5555,5556],{"class":66,"line":2420},[64,5557,157],{"class":124},[64,5559,5560,5562,5564,5566],{"class":66,"line":2425},[64,5561,137],{"class":107},[64,5563,140],{"class":111},[64,5565,143],{"class":107},[64,5567,3897],{"class":111},[64,5569,5570,5572,5574,5576],{"class":66,"line":2442},[64,5571,137],{"class":107},[64,5573,140],{"class":111},[64,5575,143],{"class":107},[64,5577,3908],{"class":111},[64,5579,5580,5582],{"class":66,"line":2447},[64,5581,2322],{"class":70},[64,5583,5584],{"class":111}," count_;\n",[64,5586,5587],{"class":66,"line":2456},[64,5588,2952],{"class":111},[64,5590,5591],{"class":66,"line":3931},[64,5592,98],{"emptyLinePlaceholder":97},[64,5594,5595,5597,5599,5601,5603,5605,5607,5609,5611,5613,5615,5617,5619,5621,5623,5625,5627,5629],{"class":66,"line":3936},[64,5596,490],{"class":70},[64,5598,4371],{"class":107},[64,5600,191],{"class":111},[64,5602,2692],{"class":107},[64,5604,140],{"class":111},[64,5606,143],{"class":107},[64,5608,140],{"class":111},[64,5610,447],{"class":107},[64,5612,2010],{"class":70},[64,5614,2705],{"class":612},[64,5616,1297],{"class":111},[64,5618,593],{"class":70},[64,5620,224],{"class":107},[64,5622,140],{"class":111},[64,5624,1306],{"class":107},[64,5626,609],{"class":70},[64,5628,1311],{"class":612},[64,5630,472],{"class":111},[64,5632,5633],{"class":66,"line":3941},[64,5634,118],{"class":111},[64,5636,5637,5639,5641,5643,5645,5647],{"class":66,"line":3952},[64,5638,209],{"class":107},[64,5640,212],{"class":111},[64,5642,215],{"class":70},[64,5644,1338],{"class":111},[64,5646,215],{"class":70},[64,5648,5649],{"class":74}," \" 开始 run，线程 id = \"\n",[64,5651,5652,5654,5656,5658,5660,5662,5664,5666,5668,5670],{"class":66,"line":3963},[64,5653,4336],{"class":70},[64,5655,224],{"class":107},[64,5657,140],{"class":111},[64,5659,4343],{"class":107},[64,5661,140],{"class":111},[64,5663,4348],{"class":107},[64,5665,655],{"class":111},[64,5667,215],{"class":70},[64,5669,224],{"class":107},[64,5671,227],{"class":111},[64,5673,5674],{"class":66,"line":3968},[64,5675,98],{"emptyLinePlaceholder":97},[64,5677,5678,5680,5682],{"class":66,"line":3985},[64,5679,4455],{"class":111},[64,5681,892],{"class":107},[64,5683,250],{"class":111},[64,5685,5686],{"class":66,"line":3990},[64,5687,98],{"emptyLinePlaceholder":97},[64,5689,5690,5692,5694,5696,5698,5700,5703,5705,5707],{"class":66,"line":3999},[64,5691,209],{"class":107},[64,5693,212],{"class":111},[64,5695,215],{"class":70},[64,5697,1338],{"class":111},[64,5699,215],{"class":70},[64,5701,5702],{"class":74}," \" run 返回\"",[64,5704,221],{"class":70},[64,5706,224],{"class":107},[64,5708,227],{"class":111},[64,5710,5711],{"class":66,"line":4004},[64,5712,296],{"class":111},[64,5714,5715],{"class":66,"line":4022},[64,5716,98],{"emptyLinePlaceholder":97},[64,5718,5719,5721,5723],{"class":66,"line":4027},[64,5720,104],{"class":70},[64,5722,108],{"class":107},[64,5724,112],{"class":111},[64,5726,5727],{"class":66,"line":4036},[64,5728,118],{"class":111},[64,5730,5732],{"class":66,"line":5731},70,[64,5733,125],{"class":124},[64,5735,5737],{"class":66,"line":5736},71,[64,5738,131],{"class":124},[64,5740,5742,5744,5746,5748],{"class":66,"line":5741},72,[64,5743,137],{"class":107},[64,5745,140],{"class":111},[64,5747,143],{"class":107},[64,5749,146],{"class":111},[64,5751,5753,5756,5759],{"class":66,"line":5752},73,[64,5754,5755],{"class":111},"    StrandCounter ",[64,5757,5758],{"class":107},"counter",[64,5760,3001],{"class":111},[64,5762,5764],{"class":66,"line":5763},74,[64,5765,98],{"emptyLinePlaceholder":97},[64,5767,5769,5771,5773,5775,5777,5779,5781,5783,5785,5787,5789,5791,5793,5795,5797,5799],{"class":66,"line":5768},75,[64,5770,209],{"class":107},[64,5772,4694],{"class":111},[64,5774,4697],{"class":107},[64,5776,191],{"class":111},[64,5778,178],{"class":107},[64,5780,140],{"class":111},[64,5782,824],{"class":107},[64,5784,4708],{"class":111},[64,5786,609],{"class":70},[64,5788,4713],{"class":111},[64,5790,178],{"class":107},[64,5792,140],{"class":111},[64,5794,1306],{"class":107},[64,5796,191],{"class":111},[64,5798,4724],{"class":74},[64,5800,1571],{"class":111},[64,5802,5804,5806,5808,5810,5812,5814,5816,5818,5820,5822,5824,5826,5828,5830,5832,5834],{"class":66,"line":5803},76,[64,5805,209],{"class":107},[64,5807,4694],{"class":111},[64,5809,4735],{"class":107},[64,5811,191],{"class":111},[64,5813,178],{"class":107},[64,5815,140],{"class":111},[64,5817,824],{"class":107},[64,5819,4708],{"class":111},[64,5821,609],{"class":70},[64,5823,4713],{"class":111},[64,5825,178],{"class":107},[64,5827,140],{"class":111},[64,5829,1306],{"class":107},[64,5831,191],{"class":111},[64,5833,4760],{"class":74},[64,5835,1571],{"class":111},[64,5837,5839],{"class":66,"line":5838},77,[64,5840,98],{"emptyLinePlaceholder":97},[64,5842,5844,5846,5848],{"class":66,"line":5843},78,[64,5845,4771],{"class":111},[64,5847,4774],{"class":107},[64,5849,250],{"class":111},[64,5851,5853,5855,5857],{"class":66,"line":5852},79,[64,5854,4781],{"class":111},[64,5856,4774],{"class":107},[64,5858,250],{"class":111},[64,5860,5862],{"class":66,"line":5861},80,[64,5863,98],{"emptyLinePlaceholder":97},[64,5865,5867,5869,5871,5873,5876,5878,5880],{"class":66,"line":5866},81,[64,5868,209],{"class":107},[64,5870,212],{"class":111},[64,5872,215],{"class":70},[64,5874,5875],{"class":74}," \"main：结束\"",[64,5877,221],{"class":70},[64,5879,224],{"class":107},[64,5881,227],{"class":111},[64,5883,5885],{"class":66,"line":5884},82,[64,5886,98],{"emptyLinePlaceholder":97},[64,5888,5890,5892,5894],{"class":66,"line":5889},83,[64,5891,284],{"class":70},[64,5893,287],{"class":194},[64,5895,290],{"class":111},[64,5897,5899],{"class":66,"line":5898},84,[64,5900,296],{"class":111},[13,5902,5903,303],{},[300,5904,302],{},[45,5906,306],{"id":5907},"编译运行-7",[55,5909,5911],{"className":309,"code":5910,"language":311,"meta":60,"style":60},"g++ demo8_strand.cpp -o demo8_strand -std=c++17 -lboost_system -pthread\n./demo8_strand\n",[21,5912,5913,5931],{"__ignoreMap":60},[64,5914,5915,5917,5920,5922,5925,5927,5929],{"class":66,"line":67},[64,5916,318],{"class":107},[64,5918,5919],{"class":74}," demo8_strand.cpp",[64,5921,324],{"class":194},[64,5923,5924],{"class":74}," demo8_strand",[64,5926,330],{"class":194},[64,5928,333],{"class":194},[64,5930,336],{"class":194},[64,5932,5933],{"class":66,"line":78},[64,5934,5935],{"class":107},"./demo8_strand\n",[45,5937,344],{"id":5938},"运行输出与时间顺序-7",[13,5940,5941,5942,3345],{},"程序启动后两个线程开始 ",[21,5943,5002],{},[55,5945,5948],{"className":5946,"code":5947,"language":350,"meta":60},[348],"线程1 开始 run，线程 id = 140000000000001\n线程2 开始 run，线程 id = 140000000000002\n",[21,5949,5947],{"__ignoreMap":60},[13,5951,5952],{},"约 1 秒后两个 timer 到期：",[55,5954,5957],{"className":5955,"code":5956,"language":350,"meta":60},[348],"timer1 回调执行，count = 1，线程 id = 140000000000001\ntimer2 回调执行，count = 2，线程 id = 140000000000002\n线程1 run 返回\n线程2 run 返回\nmain：结束\n",[21,5958,5956],{"__ignoreMap":60},[13,5960,5961,5962,5965],{},"线程 id 和 timer 顺序不固定，但 ",[21,5963,5964],{},"count"," 不会出现两个回调同时改它的并发问题。",[45,5967,373],{"id":5968},"本示例需要注意的点-6",[13,5970,5971,5973,5974,5976,5978],{},[21,5972,4992],{}," 不是让所有回调固定在同一个线程。",[17,5975],{},[21,5977,4992],{}," 是保证这些回调“不同时执行”。",[13,5980,5981],{},"也就是说，可能是：",[55,5983,5986],{"className":5984,"code":5985,"language":350,"meta":60},[348],"timer1 在线程1执行\ntimer2 在线程2执行\n",[21,5987,5985],{"__ignoreMap":60},[13,5989,5990],{},"但不会出现：",[55,5992,5995],{"className":5993,"code":5994,"language":350,"meta":60},[348],"timer1 和 timer2 同时进入 on_timer()\n",[21,5996,5994],{"__ignoreMap":60},[45,5998,6000,1061],{"id":5999},"bind_executor-说明",[21,6001,5219],{},[13,6003,3139],{},[55,6005,6007],{"className":57,"code":6006,"language":59,"meta":60,"style":60},"boost::asio::bind_executor(strand_, handler)\n",[21,6008,6009],{"__ignoreMap":60},[64,6010,6011,6013,6015,6017,6019,6021],{"class":66,"line":67},[64,6012,2692],{"class":107},[64,6014,140],{"class":111},[64,6016,143],{"class":107},[64,6018,140],{"class":111},[64,6020,5219],{"class":107},[64,6022,6023],{"class":111},"(strand_, handler)\n",[13,6025,6026,6027,6029],{},"作用：把 handler 绑定到 ",[21,6028,5115],{}," 这个执行器上。",[13,6031,6032],{},"以后 handler 执行时，会遵守这个 strand 的串行化规则。",[33,6034],{},[36,6036,6037],{"id":6037},"本节总结",[13,6039,6040],{},"你现在应该记住：",[511,6042,6043,6048,6054,6059,6065,6071,6077],{},[514,6044,6045,6047],{},[21,6046,379],{}," 是同步阻塞。",[514,6049,6050,6053],{},[21,6051,6052],{},"timer.async_wait()"," 是注册异步任务，不阻塞。",[514,6055,6056,6058],{},[21,6057,527],{}," 才是事件循环的入口。",[514,6060,6061,6062,6064],{},"一个线程 ",[21,6063,5002],{},"，回调就在这个线程里顺序执行。",[514,6066,6067,6068,6070],{},"多个线程 ",[21,6069,5002],{},"，回调可能被不同线程执行。",[514,6072,6073,6074,6076],{},"多线程共享数据时，用 ",[21,6075,4992],{}," 避免回调并发。",[514,6078,6079],{},"类里绑定成员函数的标准写法是：",[55,6081,6083],{"className":57,"code":6082,"language":59,"meta":60,"style":60},"std::bind(&ClassName::member_function,\n          this,\n          std::placeholders::_1,\n          std::placeholders::_2)\n",[21,6084,6085,6103,6110,6121],{"__ignoreMap":60},[64,6086,6087,6089,6091,6093,6095,6097,6100],{"class":66,"line":67},[64,6088,178],{"class":107},[64,6090,140],{"class":111},[64,6092,824],{"class":107},[64,6094,191],{"class":111},[64,6096,609],{"class":70},[64,6098,6099],{"class":107},"ClassName",[64,6101,6102],{"class":111},"::member_function,\n",[64,6104,6105,6108],{"class":66,"line":78},[64,6106,6107],{"class":194},"          this",[64,6109,1993],{"class":111},[64,6111,6112,6115,6117,6119],{"class":66,"line":86},[64,6113,6114],{"class":107},"          std",[64,6116,140],{"class":111},[64,6118,834],{"class":107},[64,6120,1555],{"class":111},[64,6122,6123,6125,6127,6129],{"class":66,"line":94},[64,6124,6114],{"class":107},[64,6126,140],{"class":111},[64,6128,834],{"class":107},[64,6130,6131],{"class":111},"::_2)\n",[6133,6134,6135],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":60,"searchDepth":78,"depth":78,"links":6137},[6138,6147,6158,6168,6177,6186,6193,6203,6213],{"id":38,"depth":78,"text":6139,"children":6140},"示例 1：普通 main() 里写同步定时器",[6141,6142,6143,6144,6145,6146],{"id":47,"depth":86,"text":47},{"id":53,"depth":86,"text":53},{"id":306,"depth":86,"text":306},{"id":344,"depth":86,"text":344},{"id":373,"depth":86,"text":373},{"id":403,"depth":86,"text":403},{"id":499,"depth":78,"text":6148,"children":6149},"示例 2：普通 main() 里写异步定时器",[6150,6151,6152,6153,6154,6155,6157],{"id":506,"depth":86,"text":47},{"id":540,"depth":86,"text":53},{"id":943,"depth":86,"text":306},{"id":974,"depth":86,"text":344},{"id":1020,"depth":86,"text":373},{"id":1058,"depth":86,"text":6156},"std::bind 说明",{"id":1142,"depth":86,"text":403},{"id":1186,"depth":78,"text":6159,"children":6160},"示例 3：普通 main() 里写两个异步定时器",[6161,6162,6163,6164,6165,6166],{"id":1193,"depth":86,"text":47},{"id":1224,"depth":86,"text":53},{"id":1741,"depth":86,"text":306},{"id":1772,"depth":86,"text":344},{"id":1809,"depth":86,"text":373},{"id":1836,"depth":86,"text":6167},"std::bind 里的固定参数",{"id":1904,"depth":78,"text":6169,"children":6170},"示例 4：普通 main() 里写重复定时器",[6171,6172,6173,6174,6175,6176],{"id":1911,"depth":86,"text":47},{"id":1926,"depth":86,"text":53},{"id":2465,"depth":86,"text":306},{"id":2496,"depth":86,"text":344},{"id":2533,"depth":86,"text":373},{"id":2558,"depth":86,"text":2558},{"id":2604,"depth":78,"text":2605,"children":6178},[6179,6180,6181,6182,6183,6184,6185],{"id":2608,"depth":86,"text":47},{"id":2623,"depth":86,"text":53},{"id":3077,"depth":86,"text":306},{"id":3108,"depth":86,"text":344},{"id":3136,"depth":86,"text":3136},{"id":3220,"depth":86,"text":3220},{"id":3307,"depth":86,"text":3307},{"id":3386,"depth":78,"text":3387,"children":6187},[6188,6189,6190,6191,6192],{"id":3390,"depth":86,"text":47},{"id":3413,"depth":86,"text":53},{"id":4045,"depth":86,"text":306},{"id":4076,"depth":86,"text":344},{"id":4112,"depth":86,"text":373},{"id":4142,"depth":78,"text":6194,"children":6195},"示例 7：两个线程同时运行同一个 io_context",[6196,6197,6198,6199,6200,6201],{"id":4148,"depth":86,"text":47},{"id":4166,"depth":86,"text":53},{"id":4829,"depth":86,"text":306},{"id":4860,"depth":86,"text":344},{"id":4884,"depth":86,"text":373},{"id":4905,"depth":86,"text":6202},"std::thread 里的 std::bind",{"id":4988,"depth":78,"text":6204,"children":6205},"示例 8：多线程下使用 strand 避免回调并发",[6206,6207,6208,6209,6210,6211],{"id":4996,"depth":86,"text":47},{"id":5023,"depth":86,"text":53},{"id":5907,"depth":86,"text":306},{"id":5938,"depth":86,"text":344},{"id":5968,"depth":86,"text":373},{"id":5999,"depth":86,"text":6212},"bind_executor 说明",{"id":6037,"depth":78,"text":6037},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","19.1.1",19010100,"2023-10-05","wiki/2023-10-05-cplusplus-jiao-xue","zh-cn:2023-10-05-cplusplus-jiao-xue","/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue","Cplusplus教学","md","wiki/2023-10-05-Cplusplus教学/ch19-1-1-定时器与异步IO",false,null,"/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","zh-CN","zh-cn",{},{"title":5,"description":60},"6M1vt65mjAWATVR-VTdyprtZDt9UDbt7GIzZErrPJbI",[6233,6238,6244,6250,6256,6262,6268,6274,6280,6286,6292,6298,6304,6310,6316,6322,6328,6334,6340,6346,6352,6358,6364,6370,6376,6382,6388,6394,6399,6405,6411,6417,6423,6429,6435,6441,6447,6453,6459,6465,6471,6477,6483,6489,6495,6501,6507,6513,6519,6525,6526,6532,6538,6544,6550,6556,6562,6568,6574,6580,6586,6592,6597,6602,6608,6614,6620,6626,6632,6638],{"path":6234,"stem":6235,"title":6236,"date":6217,"chapter":1467,"chapterSort":6237,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch1-c-ji-chu-chu-shi","wiki/2023-10-05-Cplusplus教学/ch1-C++基础初识","C++基础初识",1000000,{"path":6239,"stem":6240,"title":6241,"date":6217,"chapter":6242,"chapterSort":6243,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch10-nei-cun-fen-qu-yu-sheng-ming-zhou-qi","wiki/2023-10-05-Cplusplus教学/ch10-内存分区与生命周期","内存分区与生命周期","10",10000000,{"path":6245,"stem":6246,"title":6247,"date":6217,"chapter":6248,"chapterSort":6249,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch11-yin-yong","wiki/2023-10-05-Cplusplus教学/ch11-引用","引用","11",11000000,{"path":6251,"stem":6252,"title":6253,"date":6217,"chapter":6254,"chapterSort":6255,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch12-han-shu-ti-gao-yu-ming-ming-kong-jian","wiki/2023-10-05-Cplusplus教学/ch12-函数提高与命名空间","函数提高与命名空间","12",12000000,{"path":6257,"stem":6258,"title":6259,"date":6217,"chapter":6260,"chapterSort":6261,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-1-feng-zhuang","wiki/2023-10-05-Cplusplus教学/ch13-1-封装","封装","13.1",13010000,{"path":6263,"stem":6264,"title":6265,"date":6217,"chapter":6266,"chapterSort":6267,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-2-dui-xiang-chu-shi-hua-he-qing-li","wiki/2023-10-05-Cplusplus教学/ch13-2-对象初始化和清理","对象初始化和清理","13.2",13020000,{"path":6269,"stem":6270,"title":6271,"date":6217,"chapter":6272,"chapterSort":6273,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-3-dui-xiang-mo-xing-yu-this-zhi-zhen","wiki/2023-10-05-Cplusplus教学/ch13-3-对象模型与this指针","对象模型与this指针","13.3",13030000,{"path":6275,"stem":6276,"title":6277,"date":6217,"chapter":6278,"chapterSort":6279,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-4-you-yuan-yu-yun-suan-fu-zhong-zai","wiki/2023-10-05-Cplusplus教学/ch13-4-友元与运算符重载","友元与运算符重载","13.4",13040000,{"path":6281,"stem":6282,"title":6283,"date":6217,"chapter":6284,"chapterSort":6285,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-5-ji-cheng","wiki/2023-10-05-Cplusplus教学/ch13-5-继承","继承","13.5",13050000,{"path":6287,"stem":6288,"title":6289,"date":6217,"chapter":6290,"chapterSort":6291,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-6-duo-tai","wiki/2023-10-05-Cplusplus教学/ch13-6-多态","多态","13.6",13060000,{"path":6293,"stem":6294,"title":6295,"date":6217,"chapter":6296,"chapterSort":6297,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch13-lei-he-dui-xiang","wiki/2023-10-05-Cplusplus教学/ch13-类和对象","类和对象","13",13000000,{"path":6299,"stem":6300,"title":6301,"date":6217,"chapter":6302,"chapterSort":6303,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch14-wen-jian-cao-zuo","wiki/2023-10-05-Cplusplus教学/ch14-文件操作","文件操作","14",14000000,{"path":6305,"stem":6306,"title":6307,"date":6217,"chapter":6308,"chapterSort":6309,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch15-mu-ban","wiki/2023-10-05-Cplusplus教学/ch15-模板","模板","15",15000000,{"path":6311,"stem":6312,"title":6313,"date":6217,"chapter":6314,"chapterSort":6315,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-1-stl-chu-shi","wiki/2023-10-05-Cplusplus教学/ch16-1-STL初识","STL初识","16.1",16010000,{"path":6317,"stem":6318,"title":6319,"date":6217,"chapter":6320,"chapterSort":6321,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-2-std-array","wiki/2023-10-05-Cplusplus教学/ch16-2-std-array","std::array","16.2",16020000,{"path":6323,"stem":6324,"title":6325,"date":6217,"chapter":6326,"chapterSort":6327,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-3-string-rong-qi","wiki/2023-10-05-Cplusplus教学/ch16-3-string容器","string容器","16.3",16030000,{"path":6329,"stem":6330,"title":6331,"date":6217,"chapter":6332,"chapterSort":6333,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-4-vector-yu-deque-rong-qi","wiki/2023-10-05-Cplusplus教学/ch16-4-vector与deque容器","vector与deque容器","16.4",16040000,{"path":6335,"stem":6336,"title":6337,"date":6217,"chapter":6338,"chapterSort":6339,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-5-stack-queue-list-rong-qi","wiki/2023-10-05-Cplusplus教学/ch16-5-stack-queue-list容器","stack / queue / list 容器","16.5",16050000,{"path":6341,"stem":6342,"title":6343,"date":6217,"chapter":6344,"chapterSort":6345,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-6-set-map-rong-qi","wiki/2023-10-05-Cplusplus教学/ch16-6-set-map容器","set / map 容器","16.6",16060000,{"path":6347,"stem":6348,"title":6349,"date":6217,"chapter":6350,"chapterSort":6351,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-7-han-shu-dui-xiang-yu-wei-ci","wiki/2023-10-05-Cplusplus教学/ch16-7-函数对象与谓词","函数对象与谓词","16.7",16070000,{"path":6353,"stem":6354,"title":6355,"date":6217,"chapter":6356,"chapterSort":6357,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-8-chang-yong-suan-fa","wiki/2023-10-05-Cplusplus教学/ch16-8-常用算法","常用算法","16.8",16080000,{"path":6359,"stem":6360,"title":6361,"date":6217,"chapter":6362,"chapterSort":6363,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch16-stl-ti-gao-bian-cheng","wiki/2023-10-05-Cplusplus教学/ch16-STL提高编程","STL提高编程","16",16000000,{"path":6365,"stem":6366,"title":6367,"date":6217,"chapter":6368,"chapterSort":6369,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch17-c-lei-xing-zhuan-huan","wiki/2023-10-05-Cplusplus教学/ch17-C++类型转换","C++类型转换","17",17000000,{"path":6371,"stem":6372,"title":6373,"date":6217,"chapter":6374,"chapterSort":6375,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-1-auto","wiki/2023-10-05-Cplusplus教学/ch18-1-auto","auto","18.1",18010000,{"path":6377,"stem":6378,"title":6379,"date":6217,"chapter":6380,"chapterSort":6381,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-10-you-zhi-yin-yong-he-yi-dong-yu-yi","wiki/2023-10-05-Cplusplus教学/ch18-10-右值引用和移动语义","右值引用和移动语义","18.10",18100000,{"path":6383,"stem":6384,"title":6385,"date":6217,"chapter":6386,"chapterSort":6387,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-11-lambda-biao-da-shi","wiki/2023-10-05-Cplusplus教学/ch18-11-Lambda表达式","Lambda 表达式","18.11",18110000,{"path":6389,"stem":6390,"title":6391,"date":6217,"chapter":6392,"chapterSort":6393,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-12-std-function","wiki/2023-10-05-Cplusplus教学/ch18-12-std-function","std::function","18.12",18120000,{"path":6395,"stem":6396,"title":30,"date":6217,"chapter":6397,"chapterSort":6398,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-13-std-bind","wiki/2023-10-05-Cplusplus教学/ch18-13-std-bind","18.13",18130000,{"path":6400,"stem":6401,"title":6402,"date":6217,"chapter":6403,"chapterSort":6404,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-14-std-optional","wiki/2023-10-05-Cplusplus教学/ch18-14-std-optional","std::optional","18.14",18140000,{"path":6406,"stem":6407,"title":6408,"date":6217,"chapter":6409,"chapterSort":6410,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-15-std-variant","wiki/2023-10-05-Cplusplus教学/ch18-15-std-variant","std::variant","18.15",18150000,{"path":6412,"stem":6413,"title":6414,"date":6217,"chapter":6415,"chapterSort":6416,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-16-std-span","wiki/2023-10-05-Cplusplus教学/ch18-16-std-span","std::span","18.16",18160000,{"path":6418,"stem":6419,"title":6420,"date":6217,"chapter":6421,"chapterSort":6422,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-17-std-format-print","wiki/2023-10-05-Cplusplus教学/ch18-17-std-format-print","std::format / std::print","18.17",18170000,{"path":6424,"stem":6425,"title":6426,"date":6217,"chapter":6427,"chapterSort":6428,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-18-std-chrono","wiki/2023-10-05-Cplusplus教学/ch18-18-std-chrono","std::chrono","18.18",18180000,{"path":6430,"stem":6431,"title":6432,"date":6217,"chapter":6433,"chapterSort":6434,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-19-1-std-thread","wiki/2023-10-05-Cplusplus教学/ch18-19-1-std-thread","std::thread 与 join","18.19.1",18190100,{"path":6436,"stem":6437,"title":6438,"date":6217,"chapter":6439,"chapterSort":6440,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-19-2-mutex-lock-guard","wiki/2023-10-05-Cplusplus教学/ch18-19-2-mutex-lock-guard","mutex 与 lock_guard","18.19.2",18190200,{"path":6442,"stem":6443,"title":6444,"date":6217,"chapter":6445,"chapterSort":6446,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-19-3-std-atomic","wiki/2023-10-05-Cplusplus教学/ch18-19-3-std-atomic","std::atomic","18.19.3",18190300,{"path":6448,"stem":6449,"title":6450,"date":6217,"chapter":6451,"chapterSort":6452,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-19-4-condition-variable","wiki/2023-10-05-Cplusplus教学/ch18-19-4-condition-variable","condition_variable","18.19.4",18190400,{"path":6454,"stem":6455,"title":6456,"date":6217,"chapter":6457,"chapterSort":6458,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-19-bing-fa-bian-cheng","wiki/2023-10-05-Cplusplus教学/ch18-19-并发编程","并发编程","18.19",18190000,{"path":6460,"stem":6461,"title":6462,"date":6217,"chapter":6463,"chapterSort":6464,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-2-nullptr","wiki/2023-10-05-Cplusplus教学/ch18-2-nullptr","nullptr","18.2",18020000,{"path":6466,"stem":6467,"title":6468,"date":6217,"chapter":6469,"chapterSort":6470,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-20-std-filesystem","wiki/2023-10-05-Cplusplus教学/ch18-20-std-filesystem","std::filesystem","18.20",18200000,{"path":6472,"stem":6473,"title":6474,"date":6217,"chapter":6475,"chapterSort":6476,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-21-modules-jian-jie","wiki/2023-10-05-Cplusplus教学/ch18-21-modules简介","modules 简介","18.21",18210000,{"path":6478,"stem":6479,"title":6480,"date":6217,"chapter":6481,"chapterSort":6482,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-3-using","wiki/2023-10-05-Cplusplus教学/ch18-3-using","using","18.3",18030000,{"path":6484,"stem":6485,"title":6486,"date":6217,"chapter":6487,"chapterSort":6488,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-4-enum-class","wiki/2023-10-05-Cplusplus教学/ch18-4-enum-class","enum class","18.4",18040000,{"path":6490,"stem":6491,"title":6492,"date":6217,"chapter":6493,"chapterSort":6494,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-5-fan-wei-for-xun-huan","wiki/2023-10-05-Cplusplus教学/ch18-5-范围for循环","范围 for 循环","18.5",18050000,{"path":6496,"stem":6497,"title":6498,"date":6217,"chapter":6499,"chapterSort":6500,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-6-jie-gou-hua-bang-ding","wiki/2023-10-05-Cplusplus教学/ch18-6-结构化绑定","结构化绑定","18.6",18060000,{"path":6502,"stem":6503,"title":6504,"date":6217,"chapter":6505,"chapterSort":6506,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-7-constexpr","wiki/2023-10-05-Cplusplus教学/ch18-7-constexpr","constexpr","18.7",18070000,{"path":6508,"stem":6509,"title":6510,"date":6217,"chapter":6511,"chapterSort":6512,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-8-raii","wiki/2023-10-05-Cplusplus教学/ch18-8-RAII","RAII","18.8",18080000,{"path":6514,"stem":6515,"title":6516,"date":6217,"chapter":6517,"chapterSort":6518,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-9-zhi-neng-zhi-zhen","wiki/2023-10-05-Cplusplus教学/ch18-9-智能指针","智能指针","18.9",18090000,{"path":6520,"stem":6521,"title":6522,"date":6217,"chapter":6523,"chapterSort":6524,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch18-xian-dai-c","wiki/2023-10-05-Cplusplus教学/ch18-现代C++","现代C++","18",18000000,{"path":6214,"stem":6223,"title":5,"date":6217,"chapter":6215,"chapterSort":6216,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},{"path":6527,"stem":6528,"title":6529,"date":6217,"chapter":6530,"chapterSort":6531,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-2-boost-asio-ji-chu","wiki/2023-10-05-Cplusplus教学/ch19-1-2-Boost.Asio基础","Boost.Asio 基础","19.1.2",19010200,{"path":6533,"stem":6534,"title":6535,"date":6217,"chapter":6536,"chapterSort":6537,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-3-chuan-kou-tong-xin","wiki/2023-10-05-Cplusplus教学/ch19-1-3-串口通信","串口通信","19.1.3",19010300,{"path":6539,"stem":6540,"title":6541,"date":6217,"chapter":6542,"chapterSort":6543,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-4-tcp-tong-xin","wiki/2023-10-05-Cplusplus教学/ch19-1-4-TCP通信","TCP 通信","19.1.4",19010400,{"path":6545,"stem":6546,"title":6547,"date":6217,"chapter":6548,"chapterSort":6549,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-5-udp-tong-xin","wiki/2023-10-05-Cplusplus教学/ch19-1-5-UDP通信","UDP 通信","19.1.5",19010500,{"path":6551,"stem":6552,"title":6553,"date":6217,"chapter":6554,"chapterSort":6555,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-6-ji-qi-ren-gong-cheng-xie-fa-yu-ros2-ji-cheng","wiki/2023-10-05-Cplusplus教学/ch19-1-6-机器人工程写法与ROS2集成","机器人工程写法与 ROS2 集成","19.1.6",19010600,{"path":6557,"stem":6558,"title":6559,"date":6217,"chapter":6560,"chapterSort":6561,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-boost-asio-yi-bu-io-ku","wiki/2023-10-05-Cplusplus教学/ch19-1-Boost.Asio异步IO库","Boost.Asio异步IO库","19.1",19010000,{"path":6563,"stem":6564,"title":6565,"date":6217,"chapter":6566,"chapterSort":6567,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-2-eigen-xian-xing-dai-shu-ku","wiki/2023-10-05-Cplusplus教学/ch19-2-Eigen线性代数库","Eigen线性代数库","19.2",19020000,{"path":6569,"stem":6570,"title":6571,"date":6217,"chapter":6572,"chapterSort":6573,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-3-opencv-ji-suan-ji-shi-jue-ku","wiki/2023-10-05-Cplusplus教学/ch19-3-OpenCV计算机视觉库","OpenCV计算机视觉库","19.3",19030000,{"path":6575,"stem":6576,"title":6577,"date":6217,"chapter":6578,"chapterSort":6579,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-4-pcl-dian-yun-ku","wiki/2023-10-05-Cplusplus教学/ch19-4-PCL点云库","PCL点云库","19.4",19040000,{"path":6581,"stem":6582,"title":6583,"date":6217,"chapter":6584,"chapterSort":6585,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-5-sophus-li-qun-li-dai-shu-ku","wiki/2023-10-05-Cplusplus教学/ch19-5-Sophus李群李代数库","Sophus 李群李代数库","19.5",19050000,{"path":6587,"stem":6588,"title":6589,"date":6217,"chapter":6590,"chapterSort":6591,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch19-chang-yong-ku","wiki/2023-10-05-Cplusplus教学/ch19-常用库","常用库学习","19",19000000,{"path":6593,"stem":6594,"title":6595,"date":6217,"chapter":195,"chapterSort":6596,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch2-shu-ju-lei-xing-yu-shu-ju-cun-fang","wiki/2023-10-05-Cplusplus教学/ch2-数据类型与数据存放","数据类型与数据存放",2000000,{"path":6598,"stem":6599,"title":6600,"date":6217,"chapter":1498,"chapterSort":6601,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch3-shu-ru-shu-chu","wiki/2023-10-05-Cplusplus教学/ch3-输入输出","输入输出",3000000,{"path":6603,"stem":6604,"title":6605,"date":6217,"chapter":6606,"chapterSort":6607,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch4-yun-suan-fu","wiki/2023-10-05-Cplusplus教学/ch4-运算符","运算符","4",4000000,{"path":6609,"stem":6610,"title":6611,"date":6217,"chapter":6612,"chapterSort":6613,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch5-cheng-xu-liu-cheng-jie-gou","wiki/2023-10-05-Cplusplus教学/ch5-程序流程结构","程序流程结构","5",5000000,{"path":6615,"stem":6616,"title":6617,"date":6217,"chapter":6618,"chapterSort":6619,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch6-shu-zu","wiki/2023-10-05-Cplusplus教学/ch6-数组","数组","6",6000000,{"path":6621,"stem":6622,"title":6623,"date":6217,"chapter":6624,"chapterSort":6625,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch7-han-shu-yu-tou-wen-jian","wiki/2023-10-05-Cplusplus教学/ch7-函数与头文件","函数与头文件","7",7000000,{"path":6627,"stem":6628,"title":6629,"date":6217,"chapter":6630,"chapterSort":6631,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch8-zhi-zhen","wiki/2023-10-05-Cplusplus教学/ch8-指针","指针","8",8000000,{"path":6633,"stem":6634,"title":6635,"date":6217,"chapter":6636,"chapterSort":6637,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":6224},"/zh-cn/wiki/2023-10-05-cplusplus-jiao-xue/ch9-jie-gou-ti-yu-gong-yong-ti","wiki/2023-10-05-Cplusplus教学/ch9-结构体与共用体","结构体与共用体","9",9000000,{"path":6220,"stem":6639,"title":6640,"date":6217,"chapter":6225,"chapterSort":6641,"docKey":6219,"docRoot":6220,"docTitle":6221,"isWikiDoc":97,"isWikiIndex":97},"wiki/2023-10-05-Cplusplus教学/index","C/C++教程",0,{"variants":6643},[6644,6647,6650,6653,6656],{"path":6645,"localeSlug":6646,"i18nKey":6223},"/en-us/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","en-us",{"path":6648,"localeSlug":6649,"i18nKey":6223},"/zh-hant/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","zh-hant",{"path":6651,"localeSlug":6652,"i18nKey":6223},"/zh-hk/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","zh-hk",{"path":6654,"localeSlug":6655,"i18nKey":6223},"/zh-tw/wiki/2023-10-05-cplusplus-jiao-xue/ch19-1-1-ding-shi-qi-yu-yi-bu-io","zh-tw",{"path":6214,"localeSlug":6228,"i18nKey":6223},[6645,6226,6648,6226,6651,6226,6654,6226,6214,6226],1780663039263]