[{"data":1,"prerenderedAt":5637},["ShallowReactive",2],{"wiki-page-\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0200-boost-asio-ji-chu":3,"wiki-doc-items-2023-10-05-cplusplus-jiao-xue":5079,"wiki:author-members":5625},{"id":4,"title":5,"authors":6,"body":8,"chapterDepth":98,"chapterOrder":5067,"date":5068,"description":80,"docKey":5069,"docRoot":5070,"docTitle":5071,"extension":5072,"isWikiDoc":109,"isWikiIndex":5073,"meta":5074,"navigation":109,"path":5075,"seo":5076,"stem":5077,"wikiDepth":87,"__hash__":5078},"wiki\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0200-Boost.Asio基础.md","Boost.Asio 基础",[7],"董佳辉",{"type":9,"value":10,"toc":5006},"minimark",[11,43,46,57,61,71,74,266,273,276,279,287,290,295,301,304,310,315,318,324,326,337,340,352,355,691,695,698,701,707,710,718,721,735,741,762,765,784,787,793,821,824,840,842,852,855,861,870,876,882,885,897,900,903,930,933,939,942,945,951,954,957,963,968,971,981,984,990,993,1005,1008,1010,1016,1019,1045,1048,1054,1057,1063,1069,1075,1078,1084,1087,1093,1096,1102,1104,1120,1123,1129,1132,1144,1147,1157,1167,1169,1175,1178,1208,1211,1217,1224,1227,1233,1236,1242,1245,1251,1256,1259,1265,1268,1278,1281,1307,1313,1315,1318,1321,1327,1860,1863,1869,1872,1874,1877,1880,1895,1897,1903,1906,1932,1938,1944,1947,1966,1969,1994,2000,2003,2015,2018,2024,2027,2033,2036,2048,2051,2053,2057,2060,2084,2087,2140,2145,2155,2158,2164,2169,2175,2178,2180,2187,2190,2204,2207,2213,2216,2222,2225,2231,2234,2244,2247,2253,2255,2261,2267,2273,2275,2289,2292,2298,2301,2307,2310,2312,2316,2319,2355,2358,2364,2370,2376,2379,2385,2388,2394,2400,2402,2410,2413,2450,2453,2465,2468,2474,2479,2485,2487,2493,2496,2499,2501,2511,2514,2519,2529,2532,2538,2541,2555,2558,2568,2571,2577,2579,2585,2588,2594,2597,2609,2612,2624,2626,2630,2633,2639,2642,2654,2657,2663,2666,2672,2675,2681,2684,2690,2696,2703,2705,2714,2716,2743,2746,2752,2755,2767,2769,2775,2778,2784,2786,2792,2794,2797,2802,2808,2813,2819,2822,2828,2831,2843,2845,2852,2855,2858,2878,2881,2884,3125,3129,3132,3138,3141,3147,3150,3156,3159,3223,3234,3237,3243,3249,3255,3260,3267,3273,3276,3284,3287,3401,3403,3456,3459,3521,3524,3567,3570,3576,3578,3629,3632,3638,3641,3705,3707,3710,3744,3746,3774,3777,3779,3782,3801,3804,3830,3833,3835,3841,3843,3862,3864,3883,3886,3892,3895,3898,3904,3906,3909,3919,3921,3963,3971,3974,4018,4021,4027,4030,4048,4051,4056,4058,4065,4068,4078,4105,4108,4890,4894,4897,4900,4906,4909,4915,4918,4924,4927,4930,4933,4947,4953,4956,4962,4964,4967,5002],[12,13,14],"blockquote",{},[15,16,17,18,22,23,22,26,22,29,22,32,22,35,38,39,42],"p",{},"本节不急着讲串口、TCP、UDP，而是把 ",[19,20,21],"code",{},"io_context","、",[19,24,25],{},"run()",[19,27,28],{},"post()",[19,30,31],{},"work_guard",[19,33,34],{},"buffer",[19,36,37],{},"std::bind","、对象生命周期这些基础讲清楚。",[40,41],"br",{},"\n这些东西如果没搞懂，后面串口和网络程序会出现“为什么回调不执行”“为什么程序直接退出”“为什么段错误”等问题。",[44,45],"hr",{},[47,48,50,51,53,54,56],"h2",{"id":49},"示例-1io_context-没有任务时run-立刻返回","示例 1：",[19,52,21],{}," 没有任务时，",[19,55,25],{}," 立刻返回",[58,59,60],"h3",{"id":60},"程序目标",[15,62,63,64,66,67,70],{},"验证一个非常重要的现象：如果 ",[19,65,21],{}," 里没有任何未完成任务，",[19,68,69],{},"io.run()"," 会立刻返回。",[58,72,73],{"id":73},"完整代码",[75,76,81],"pre",{"className":77,"code":78,"language":79,"meta":80,"style":80},"language-cpp shiki shiki-themes github-light github-dark","#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cprint>\n\nint main()\n{\n    \u002F\u002F 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    std::println(\"main：准备调用 io.run()\");\n\n    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n    std::size_t count = io.run();\n\n    std::println(\"main：io.run() 返回，执行了 {} 个回调\", count);\n\n    return 0;\n}\n","cpp","",[19,82,83,96,104,111,125,131,138,144,159,164,184,189,195,220,225,242,247,260],{"__ignoreMap":80},[84,85,88,92],"span",{"class":86,"line":87},"line",1,[84,89,91],{"class":90},"szBVR","#include",[84,93,95],{"class":94},"sZZnC"," \u003Cboost\u002Fasio.hpp>\n",[84,97,99,101],{"class":86,"line":98},2,[84,100,91],{"class":90},[84,102,103],{"class":94}," \u003Cprint>\n",[84,105,107],{"class":86,"line":106},3,[84,108,110],{"emptyLinePlaceholder":109},true,"\n",[84,112,114,117,121],{"class":86,"line":113},4,[84,115,116],{"class":90},"int",[84,118,120],{"class":119},"sScJk"," main",[84,122,124],{"class":123},"sVt8B","()\n",[84,126,128],{"class":86,"line":127},5,[84,129,130],{"class":123},"{\n",[84,132,134],{"class":86,"line":133},6,[84,135,137],{"class":136},"sJ8bj","    \u002F\u002F 程序从 main 函数开始执行，下面的语句会按顺序运行。\n",[84,139,141],{"class":86,"line":140},7,[84,142,143],{"class":136},"    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n",[84,145,147,150,153,156],{"class":86,"line":146},8,[84,148,149],{"class":119},"    boost",[84,151,152],{"class":123},"::",[84,154,155],{"class":119},"asio",[84,157,158],{"class":123},"::io_context io;\n",[84,160,162],{"class":86,"line":161},9,[84,163,110],{"emptyLinePlaceholder":109},[84,165,167,170,172,175,178,181],{"class":86,"line":166},10,[84,168,169],{"class":119},"    std",[84,171,152],{"class":123},[84,173,174],{"class":119},"println",[84,176,177],{"class":123},"(",[84,179,180],{"class":94},"\"main：准备调用 io.run()\"",[84,182,183],{"class":123},");\n",[84,185,187],{"class":86,"line":186},11,[84,188,110],{"emptyLinePlaceholder":109},[84,190,192],{"class":86,"line":191},12,[84,193,194],{"class":136},"    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n",[84,196,198,200,202,205,208,211,214,217],{"class":86,"line":197},13,[84,199,169],{"class":119},[84,201,152],{"class":123},[84,203,204],{"class":90},"size_t",[84,206,207],{"class":123}," count ",[84,209,210],{"class":90},"=",[84,212,213],{"class":123}," io.",[84,215,216],{"class":119},"run",[84,218,219],{"class":123},"();\n",[84,221,223],{"class":86,"line":222},14,[84,224,110],{"emptyLinePlaceholder":109},[84,226,228,230,232,234,236,239],{"class":86,"line":227},15,[84,229,169],{"class":119},[84,231,152],{"class":123},[84,233,174],{"class":119},[84,235,177],{"class":123},[84,237,238],{"class":94},"\"main：io.run() 返回，执行了 {} 个回调\"",[84,240,241],{"class":123},", count);\n",[84,243,245],{"class":86,"line":244},16,[84,246,110],{"emptyLinePlaceholder":109},[84,248,250,253,257],{"class":86,"line":249},17,[84,251,252],{"class":90},"    return",[84,254,256],{"class":255},"sj4cs"," 0",[84,258,259],{"class":123},";\n",[84,261,263],{"class":86,"line":262},18,[84,264,265],{"class":123},"}\n",[15,267,268,272],{},[269,270,271],"strong",{},"运行结果","：见下方“运行输出与时间顺序”；如果示例涉及定时器、线程、网络或外部设备，具体时间和顺序可能会随环境略有变化。",[58,274,275],{"id":275},"运行输出与时间顺序",[15,277,278],{},"这个程序不会等待，立刻输出：",[75,280,285],{"className":281,"code":283,"language":284,"meta":80},[282],"language-text","main：准备调用 io.run()\nmain：io.run() 返回，执行了 0 个回调\n","text",[19,286,283],{"__ignoreMap":80},[58,288,289],{"id":289},"本示例需要注意的点",[15,291,292,294],{},[19,293,69],{}," 不是永远阻塞。它阻塞的前提是：",[75,296,299],{"className":297,"code":298,"language":284,"meta":80},[282],"io_context 里还有未完成的异步任务，或者还有 work_guard 保持它不退出。\n",[19,300,298],{"__ignoreMap":80},[15,302,303],{},"如果什么任务都没有，它会马上返回。",[58,305,307,309],{"id":306},"iorun-返回值",[19,308,69],{}," 返回值",[15,311,312,314],{},[19,313,69],{}," 返回值表示执行了多少个 handler。",[15,316,317],{},"本例中没有任何任务，所以返回值是：",[75,319,322],{"className":320,"code":321,"language":284,"meta":80},[282],"0\n",[19,323,321],{"__ignoreMap":80},[44,325],{},[47,327,329,330,333,334,336],{"id":328},"示例-2普通-main-里用-post-投递任务","示例 2：普通 ",[19,331,332],{},"main()"," 里用 ",[19,335,28],{}," 投递任务",[58,338,60],{"id":339},"程序目标-1",[15,341,342,345,346,348,349,351],{},[19,343,344],{},"boost::asio::post()"," 可以把一个普通函数投递到 ",[19,347,21],{}," 里，让它以后由 ",[19,350,69],{}," 执行。",[58,353,73],{"id":354},"完整代码-1",[75,356,358],{"className":77,"code":357,"language":79,"meta":80,"style":80},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cfunctional>\n#include \u003Cprint>\n#include \u003Cstring>\n\nvoid print_msg(const std::string& msg)\n{\n    std::println(\"执行任务：{}\", msg);\n}\n\nint main()\n{\n    \u002F\u002F 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io;\n\n    std::println(\"main：投递任务 A\");\n    \u002F\u002F post 只是把任务放进队列，真正执行要等 io.run()。\n    boost::asio::post(io, std::bind(print_msg, std::string(\"A\")));\n\n    std::println(\"main：投递任务 B\");\n    boost::asio::post(io, std::bind(print_msg, std::string(\"B\")));\n\n    std::println(\"main：准备调用 io.run()\");\n\n    \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n    std::size_t count = io.run();\n\n    std::println(\"main：io.run() 返回，执行了 {} 个任务\", count);\n\n    return 0;\n}\n",[19,359,360,366,373,379,386,390,421,425,441,445,449,457,461,465,469,479,483,498,503,545,550,566,602,607,622,627,632,651,656,672,677,686],{"__ignoreMap":80},[84,361,362,364],{"class":86,"line":87},[84,363,91],{"class":90},[84,365,95],{"class":94},[84,367,368,370],{"class":86,"line":98},[84,369,91],{"class":90},[84,371,372],{"class":94}," \u003Cfunctional>\n",[84,374,375,377],{"class":86,"line":106},[84,376,91],{"class":90},[84,378,103],{"class":94},[84,380,381,383],{"class":86,"line":113},[84,382,91],{"class":90},[84,384,385],{"class":94}," \u003Cstring>\n",[84,387,388],{"class":86,"line":127},[84,389,110],{"emptyLinePlaceholder":109},[84,391,392,395,398,400,403,406,408,411,414,418],{"class":86,"line":133},[84,393,394],{"class":90},"void",[84,396,397],{"class":119}," print_msg",[84,399,177],{"class":123},[84,401,402],{"class":90},"const",[84,404,405],{"class":119}," std",[84,407,152],{"class":123},[84,409,410],{"class":119},"string",[84,412,413],{"class":90},"&",[84,415,417],{"class":416},"s4XuR"," msg",[84,419,420],{"class":123},")\n",[84,422,423],{"class":86,"line":140},[84,424,130],{"class":123},[84,426,427,429,431,433,435,438],{"class":86,"line":146},[84,428,169],{"class":119},[84,430,152],{"class":123},[84,432,174],{"class":119},[84,434,177],{"class":123},[84,436,437],{"class":94},"\"执行任务：{}\"",[84,439,440],{"class":123},", msg);\n",[84,442,443],{"class":86,"line":161},[84,444,265],{"class":123},[84,446,447],{"class":86,"line":166},[84,448,110],{"emptyLinePlaceholder":109},[84,450,451,453,455],{"class":86,"line":186},[84,452,116],{"class":90},[84,454,120],{"class":119},[84,456,124],{"class":123},[84,458,459],{"class":86,"line":191},[84,460,130],{"class":123},[84,462,463],{"class":86,"line":197},[84,464,137],{"class":136},[84,466,467],{"class":86,"line":222},[84,468,143],{"class":136},[84,470,471,473,475,477],{"class":86,"line":227},[84,472,149],{"class":119},[84,474,152],{"class":123},[84,476,155],{"class":119},[84,478,158],{"class":123},[84,480,481],{"class":86,"line":244},[84,482,110],{"emptyLinePlaceholder":109},[84,484,485,487,489,491,493,496],{"class":86,"line":249},[84,486,169],{"class":119},[84,488,152],{"class":123},[84,490,174],{"class":119},[84,492,177],{"class":123},[84,494,495],{"class":94},"\"main：投递任务 A\"",[84,497,183],{"class":123},[84,499,500],{"class":86,"line":262},[84,501,502],{"class":136},"    \u002F\u002F post 只是把任务放进队列，真正执行要等 io.run()。\n",[84,504,506,508,510,512,514,517,520,523,525,528,531,533,535,537,539,542],{"class":86,"line":505},19,[84,507,149],{"class":119},[84,509,152],{"class":123},[84,511,155],{"class":119},[84,513,152],{"class":123},[84,515,516],{"class":119},"post",[84,518,519],{"class":123},"(io, ",[84,521,522],{"class":119},"std",[84,524,152],{"class":123},[84,526,527],{"class":119},"bind",[84,529,530],{"class":123},"(print_msg, ",[84,532,522],{"class":119},[84,534,152],{"class":123},[84,536,410],{"class":119},[84,538,177],{"class":123},[84,540,541],{"class":94},"\"A\"",[84,543,544],{"class":123},")));\n",[84,546,548],{"class":86,"line":547},20,[84,549,110],{"emptyLinePlaceholder":109},[84,551,553,555,557,559,561,564],{"class":86,"line":552},21,[84,554,169],{"class":119},[84,556,152],{"class":123},[84,558,174],{"class":119},[84,560,177],{"class":123},[84,562,563],{"class":94},"\"main：投递任务 B\"",[84,565,183],{"class":123},[84,567,569,571,573,575,577,579,581,583,585,587,589,591,593,595,597,600],{"class":86,"line":568},22,[84,570,149],{"class":119},[84,572,152],{"class":123},[84,574,155],{"class":119},[84,576,152],{"class":123},[84,578,516],{"class":119},[84,580,519],{"class":123},[84,582,522],{"class":119},[84,584,152],{"class":123},[84,586,527],{"class":119},[84,588,530],{"class":123},[84,590,522],{"class":119},[84,592,152],{"class":123},[84,594,410],{"class":119},[84,596,177],{"class":123},[84,598,599],{"class":94},"\"B\"",[84,601,544],{"class":123},[84,603,605],{"class":86,"line":604},23,[84,606,110],{"emptyLinePlaceholder":109},[84,608,610,612,614,616,618,620],{"class":86,"line":609},24,[84,611,169],{"class":119},[84,613,152],{"class":123},[84,615,174],{"class":119},[84,617,177],{"class":123},[84,619,180],{"class":94},[84,621,183],{"class":123},[84,623,625],{"class":86,"line":624},25,[84,626,110],{"emptyLinePlaceholder":109},[84,628,630],{"class":86,"line":629},26,[84,631,194],{"class":136},[84,633,635,637,639,641,643,645,647,649],{"class":86,"line":634},27,[84,636,169],{"class":119},[84,638,152],{"class":123},[84,640,204],{"class":90},[84,642,207],{"class":123},[84,644,210],{"class":90},[84,646,213],{"class":123},[84,648,216],{"class":119},[84,650,219],{"class":123},[84,652,654],{"class":86,"line":653},28,[84,655,110],{"emptyLinePlaceholder":109},[84,657,659,661,663,665,667,670],{"class":86,"line":658},29,[84,660,169],{"class":119},[84,662,152],{"class":123},[84,664,174],{"class":119},[84,666,177],{"class":123},[84,668,669],{"class":94},"\"main：io.run() 返回，执行了 {} 个任务\"",[84,671,241],{"class":123},[84,673,675],{"class":86,"line":674},30,[84,676,110],{"emptyLinePlaceholder":109},[84,678,680,682,684],{"class":86,"line":679},31,[84,681,252],{"class":90},[84,683,256],{"class":255},[84,685,259],{"class":123},[84,687,689],{"class":86,"line":688},32,[84,690,265],{"class":123},[15,692,693,272],{},[269,694,271],{},[58,696,275],{"id":697},"运行输出与时间顺序-1",[15,699,700],{},"程序立刻输出：",[75,702,705],{"className":703,"code":704,"language":284,"meta":80},[282],"main：投递任务 A\nmain：投递任务 B\nmain：准备调用 io.run()\n执行任务：A\n执行任务：B\nmain：io.run() 返回，执行了 2 个任务\n",[19,706,704],{"__ignoreMap":80},[58,708,289],{"id":709},"本示例需要注意的点-1",[15,711,712,714,715,717],{},[19,713,28],{}," 不是立刻执行函数，而是把函数放进 ",[19,716,21],{}," 的任务队列。",[15,719,720],{},"真正执行发生在：",[75,722,724],{"className":77,"code":723,"language":79,"meta":80,"style":80},"io.run();\n",[19,725,726],{"__ignoreMap":80},[84,727,728,731,733],{"class":86,"line":87},[84,729,730],{"class":123},"io.",[84,732,216],{"class":119},[84,734,219],{"class":123},[58,736,738,740],{"id":737},"post-函数说明",[19,739,28],{}," 函数说明",[75,742,744],{"className":77,"code":743,"language":79,"meta":80,"style":80},"boost::asio::post(io, handler);\n",[19,745,746],{"__ignoreMap":80},[84,747,748,751,753,755,757,759],{"class":86,"line":87},[84,749,750],{"class":119},"boost",[84,752,152],{"class":123},[84,754,155],{"class":119},[84,756,152],{"class":123},[84,758,516],{"class":119},[84,760,761],{"class":123},"(io, handler);\n",[15,763,764],{},"参数：",[766,767,768,778],"ol",{},[769,770,771,774,775,777],"li",{},[19,772,773],{},"io","：任务投递到哪个 ",[19,776,21],{},"；",[769,779,780,783],{},[19,781,782],{},"handler","：将来要执行的函数对象。",[15,785,786],{},"返回值：通常不用关心。",[58,788,790,792],{"id":789},"stdbind-说明",[19,791,37],{}," 说明",[75,794,796],{"className":77,"code":795,"language":79,"meta":80,"style":80},"std::bind(print_msg, std::string(\"A\"))\n",[19,797,798],{"__ignoreMap":80},[84,799,800,802,804,806,808,810,812,814,816,818],{"class":86,"line":87},[84,801,522],{"class":119},[84,803,152],{"class":123},[84,805,527],{"class":119},[84,807,530],{"class":123},[84,809,522],{"class":119},[84,811,152],{"class":123},[84,813,410],{"class":119},[84,815,177],{"class":123},[84,817,541],{"class":94},[84,819,820],{"class":123},"))\n",[15,822,823],{},"表示生成一个“无参数函数对象”。以后执行它时，相当于执行：",[75,825,827],{"className":77,"code":826,"language":79,"meta":80,"style":80},"print_msg(\"A\");\n",[19,828,829],{"__ignoreMap":80},[84,830,831,834,836,838],{"class":86,"line":87},[84,832,833],{"class":119},"print_msg",[84,835,177],{"class":123},[84,837,541],{"class":94},[84,839,183],{"class":123},[44,841],{},[47,843,845,846,848,849,851],{"id":844},"示例-3work_guard-让-iorun-等待未来任务","示例 3：",[19,847,31],{}," 让 ",[19,850,69],{}," 等待未来任务",[58,853,60],{"id":854},"程序目标-2",[15,856,857,858,860],{},"首先要理解 ",[19,859,69],{}," 一个非常重要的规则：",[12,862,863],{},[15,864,865],{},[269,866,867,869],{},[19,868,69],{}," 不是一个永远运行的死循环。",[15,871,872,873,875],{},"当 ",[19,874,21],{}," 发现：",[75,877,880],{"className":878,"code":879,"language":284,"meta":80},[282],"现在没有 handler 可以执行\n\n并且\n\n以后也没有已经登记的异步工作需要等待\n",[19,881,879],{"__ignoreMap":80},[15,883,884],{},"那么：",[75,886,887],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,888,889],{"__ignoreMap":80},[84,890,891,893,895],{"class":86,"line":87},[84,892,730],{"class":123},[84,894,216],{"class":119},[84,896,219],{"class":123},[15,898,899],{},"就会直接返回。",[15,901,902],{},"例如：",[75,904,906],{"className":77,"code":905,"language":79,"meta":80,"style":80},"boost::asio::io_context io;\n\nio.run();\n",[19,907,908,918,922],{"__ignoreMap":80},[84,909,910,912,914,916],{"class":86,"line":87},[84,911,750],{"class":119},[84,913,152],{"class":123},[84,915,155],{"class":119},[84,917,158],{"class":123},[84,919,920],{"class":86,"line":98},[84,921,110],{"emptyLinePlaceholder":109},[84,923,924,926,928],{"class":86,"line":106},[84,925,730],{"class":123},[84,927,216],{"class":119},[84,929,219],{"class":123},[15,931,932],{},"这里什么任务都没有，所以：",[75,934,937],{"className":935,"code":936,"language":284,"meta":80},[282],"进入 run()\n↓\n发现没有任何工作\n↓\n立即返回\n",[19,938,936],{"__ignoreMap":80},[15,940,941],{},"这对于机器人通信线程就可能产生一个问题。",[15,943,944],{},"假设程序启动时先创建 Asio 线程：",[75,946,949],{"className":947,"code":948,"language":284,"meta":80},[282],"通信线程\n↓\nio.run()\n",[19,950,948],{"__ignoreMap":80},[15,952,953],{},"但是串口、定时器或者其他任务要等一会儿才从别的线程提交。",[15,955,956],{},"那么可能发生：",[75,958,961],{"className":959,"code":960,"language":284,"meta":80},[282],"Asio 线程启动\n↓\nio.run()\n↓\n此时任务队列为空\n↓\nrun() 认为已经没事可做\n↓\n直接返回\n↓\nAsio 通信线程结束\n\n过了 2 秒\n↓\n其他线程才 post() 一个任务\n↓\n已经没有线程在 run() 了\n↓\n这个任务没人执行\n",[19,962,960],{"__ignoreMap":80},[15,964,965,967],{},[19,966,31],{}," 就是为了解决这种情况。",[15,969,970],{},"可以先把它理解成：",[12,972,973],{},[15,974,975],{},[269,976,977,978,980],{},"给 ",[19,979,21],{}," 人为登记一份“还有工作没有完成”的占位工作。",[15,982,983],{},"只要这个 guard 还有效：",[75,985,988],{"className":986,"code":987,"language":284,"meta":80},[282],"io_context：\n虽然现在任务队列是空的，\n\n但还有一份 outstanding work，\n\n所以我不能认为工作已经全部结束。\n",[19,989,987],{"__ignoreMap":80},[15,991,992],{},"于是：",[75,994,995],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,996,997],{"__ignoreMap":80},[84,998,999,1001,1003],{"class":86,"line":87},[84,1000,730],{"class":123},[84,1002,216],{"class":119},[84,1004,219],{"class":123},[15,1006,1007],{},"不会因为“暂时没任务”而返回，而是继续阻塞等待以后可能到来的任务。",[44,1009],{},[58,1011,1013,1014],{"id":1012},"如果没有-work_guard","如果没有 ",[19,1015,31],{},[15,1017,1018],{},"先看这个过程：",[75,1020,1021],{"className":77,"code":905,"language":79,"meta":80,"style":80},[19,1022,1023,1033,1037],{"__ignoreMap":80},[84,1024,1025,1027,1029,1031],{"class":86,"line":87},[84,1026,750],{"class":119},[84,1028,152],{"class":123},[84,1030,155],{"class":119},[84,1032,158],{"class":123},[84,1034,1035],{"class":86,"line":98},[84,1036,110],{"emptyLinePlaceholder":109},[84,1038,1039,1041,1043],{"class":86,"line":106},[84,1040,730],{"class":123},[84,1042,216],{"class":119},[84,1044,219],{"class":123},[15,1046,1047],{},"此时：",[75,1049,1052],{"className":1050,"code":1051,"language":284,"meta":80},[282],"任务数量 = 0\n未完成异步操作 = 0\nwork_guard = 0\n",[19,1053,1051],{"__ignoreMap":80},[15,1055,1056],{},"所以：",[75,1058,1061],{"className":1059,"code":1060,"language":284,"meta":80},[282],"io.run()\n↓\n没有任何工作\n↓\n直接返回\n",[19,1062,1060],{"__ignoreMap":80},[15,1064,1065,1066,1068],{},"可以把 ",[19,1067,25],{}," 粗略理解成：",[75,1070,1073],{"className":1071,"code":1072,"language":284,"meta":80},[282],"while (还有工作需要处理)\n{\n    等待事件\n    执行 handler\n}\n\nreturn;\n",[19,1074,1072],{"__ignoreMap":80},[15,1076,1077],{},"注意这里的：",[75,1079,1082],{"className":1080,"code":1081,"language":284,"meta":80},[282],"还有工作\n",[19,1083,1081],{"__ignoreMap":80},[15,1085,1086],{},"不只是指：",[75,1088,1091],{"className":1089,"code":1090,"language":284,"meta":80},[282],"当前任务队列里已经有 handler\n",[19,1092,1090],{"__ignoreMap":80},[15,1094,1095],{},"也包括：",[75,1097,1100],{"className":1098,"code":1099,"language":284,"meta":80},[282],"已经启动但还没有完成的异步操作\n",[19,1101,1099],{"__ignoreMap":80},[15,1103,902],{},[75,1105,1107],{"className":77,"code":1106,"language":79,"meta":80,"style":80},"timer.async_wait(...);\n",[19,1108,1109],{"__ignoreMap":80},[84,1110,1111,1114,1117],{"class":86,"line":87},[84,1112,1113],{"class":123},"timer.",[84,1115,1116],{"class":119},"async_wait",[84,1118,1119],{"class":123},"(...);\n",[15,1121,1122],{},"虽然 timer 还要 2 秒才到期，但 Asio 已经知道：",[75,1124,1127],{"className":1125,"code":1126,"language":284,"meta":80},[282],"这里还有一个异步操作没完成\n",[19,1128,1126],{"__ignoreMap":80},[15,1130,1131],{},"所以这种情况下：",[75,1133,1134],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,1135,1136],{"__ignoreMap":80},[84,1137,1138,1140,1142],{"class":86,"line":87},[84,1139,730],{"class":123},[84,1141,216],{"class":119},[84,1143,219],{"class":123},[15,1145,1146],{},"本来就不会立刻返回。",[15,1148,1149,1150,1153,1154,1156],{},"这也是为什么用 ",[19,1151,1152],{},"timer.async_wait()"," 来演示 ",[19,1155,31],{}," 并不好：",[12,1158,1159],{},[15,1160,1161],{},[269,1162,1163,1164,1166],{},"timer 自己已经能够让 ",[19,1165,69],{}," 保持运行，反而看不出 guard 的作用。",[44,1168],{},[58,1170,1172,1174],{"id":1171},"work_guard-到底做了什么",[19,1173,31],{}," 到底做了什么",[15,1176,1177],{},"创建：",[75,1179,1181],{"className":77,"code":1180,"language":79,"meta":80,"style":80},"auto guard = boost::asio::make_work_guard(io);\n",[19,1182,1183],{"__ignoreMap":80},[84,1184,1185,1188,1191,1193,1196,1198,1200,1202,1205],{"class":86,"line":87},[84,1186,1187],{"class":90},"auto",[84,1189,1190],{"class":123}," guard ",[84,1192,210],{"class":90},[84,1194,1195],{"class":119}," boost",[84,1197,152],{"class":123},[84,1199,155],{"class":119},[84,1201,152],{"class":123},[84,1203,1204],{"class":119},"make_work_guard",[84,1206,1207],{"class":123},"(io);\n",[15,1209,1210],{},"以后，可以粗略理解成：",[75,1212,1215],{"className":1213,"code":1214,"language":284,"meta":80},[282],"io_context 内部的“未完成工作数量”\n额外 +1\n",[19,1216,1214],{"__ignoreMap":80},[15,1218,1219,1220,1223],{},"注意，这里的 ",[19,1221,1222],{},"+1"," 只是帮助理解，并不代表内部真的就是一个简单整数。",[15,1225,1226],{},"可以想象成：",[75,1228,1231],{"className":1229,"code":1230,"language":284,"meta":80},[282],"创建 io_context\n\n未完成工作：\n0\n",[19,1232,1230],{"__ignoreMap":80},[15,1234,1235],{},"创建 guard：",[75,1237,1240],{"className":1238,"code":1239,"language":284,"meta":80},[282],"make_work_guard(io)\n\n未完成工作：\n0 + 一份 guard 占位工作\n",[19,1241,1239],{"__ignoreMap":80},[15,1243,1244],{},"于是即使现在：",[75,1246,1249],{"className":1247,"code":1248,"language":284,"meta":80},[282],"没有 timer\n\n没有 socket\n\n没有 post 的 handler\n\n没有任何真正任务\n",[19,1250,1248],{"__ignoreMap":80},[15,1252,1253,1255],{},[19,1254,69],{}," 看到 guard 还持有 outstanding work，也不会退出。",[15,1257,1258],{},"它会：",[75,1260,1263],{"className":1261,"code":1262,"language":284,"meta":80},[282],"没有任务\n↓\n但是 guard 还在\n↓\n不能返回\n↓\n阻塞等待新任务\n",[19,1264,1262],{"__ignoreMap":80},[15,1266,1267],{},"注意：",[12,1269,1270],{},[15,1271,1272,1274,1275,1277],{},[19,1273,31],{}," 不会让 ",[19,1276,69],{}," 疯狂空转。",[15,1279,1280],{},"它不是：",[75,1282,1284],{"className":77,"code":1283,"language":79,"meta":80,"style":80},"while (true)\n{\n}\n",[19,1285,1286,1299,1303],{"__ignoreMap":80},[84,1287,1288,1291,1294,1297],{"class":86,"line":87},[84,1289,1290],{"class":90},"while",[84,1292,1293],{"class":123}," (",[84,1295,1296],{"class":255},"true",[84,1298,420],{"class":123},[84,1300,1301],{"class":86,"line":98},[84,1302,130],{"class":123},[84,1304,1305],{"class":86,"line":106},[84,1306,265],{"class":123},[15,1308,1309,1310,1312],{},"没有任务时，",[19,1311,69],{}," 仍然可以阻塞等待，不会因为 guard 就白白占满一个 CPU 核心。",[44,1314],{},[58,1316,73],{"id":1317},"完整代码-2",[15,1319,1320],{},"这个例子真正模拟：",[75,1322,1325],{"className":1323,"code":1324,"language":284,"meta":80},[282],"Asio 通信线程已经启动\n\n但当前没有任何任务\n\n2 秒以后另一个线程才提交任务\n",[19,1326,1324],{"__ignoreMap":80},[75,1328,1330],{"className":77,"code":1329,"language":79,"meta":80,"style":80},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cchrono>\n#include \u003Cfunctional>\n#include \u003Cprint>\n#include \u003Cthread>\n\nusing namespace std::chrono_literals;\n\nusing WorkGuard =\n    boost::asio::executor_work_guard\u003C\n        boost::asio::io_context::executor_type>;\n\nvoid delayed_post(\n    boost::asio::io_context* io,\n    WorkGuard* guard)\n{\n    std::println(\"工作线程：等待 2 秒再提交任务\");\n\n    std::this_thread::sleep_for(2s);\n\n    std::println(\"工作线程：向 io_context 提交任务\");\n\n    boost::asio::post(\n        *io,\n        [] {\n            std::println(\n                \"Asio handler：收到后来提交的任务\");\n        });\n\n    std::println(\"工作线程：释放 work_guard\");\n\n    guard->reset();\n}\n\nint main()\n{\n    boost::asio::io_context io;\n\n    WorkGuard guard =\n        boost::asio::make_work_guard(io);\n\n    std::thread worker(\n        std::bind(\n            delayed_post,\n            &io,\n            &guard));\n\n    std::println(\"main：开始 io.run()\");\n\n    std::size_t count = io.run();\n\n    std::println(\n        \"main：io.run() 返回，执行了 {} 个 handler\",\n        count);\n\n    worker.join();\n\n    return 0;\n}\n",[19,1331,1332,1338,1345,1351,1357,1364,1368,1385,1389,1399,1413,1434,1438,1448,1469,1481,1485,1500,1504,1528,1532,1547,1551,1565,1573,1578,1589,1596,1601,1605,1620,1624,1634,1639,1644,1653,1658,1669,1674,1683,1698,1703,1716,1728,1734,1742,1750,1755,1771,1776,1795,1800,1811,1819,1825,1830,1841,1846,1855],{"__ignoreMap":80},[84,1333,1334,1336],{"class":86,"line":87},[84,1335,91],{"class":90},[84,1337,95],{"class":94},[84,1339,1340,1342],{"class":86,"line":98},[84,1341,91],{"class":90},[84,1343,1344],{"class":94}," \u003Cchrono>\n",[84,1346,1347,1349],{"class":86,"line":106},[84,1348,91],{"class":90},[84,1350,372],{"class":94},[84,1352,1353,1355],{"class":86,"line":113},[84,1354,91],{"class":90},[84,1356,103],{"class":94},[84,1358,1359,1361],{"class":86,"line":127},[84,1360,91],{"class":90},[84,1362,1363],{"class":94}," \u003Cthread>\n",[84,1365,1366],{"class":86,"line":133},[84,1367,110],{"emptyLinePlaceholder":109},[84,1369,1370,1373,1376,1378,1380,1383],{"class":86,"line":140},[84,1371,1372],{"class":90},"using",[84,1374,1375],{"class":90}," namespace",[84,1377,405],{"class":119},[84,1379,152],{"class":123},[84,1381,1382],{"class":119},"chrono_literals",[84,1384,259],{"class":123},[84,1386,1387],{"class":86,"line":146},[84,1388,110],{"emptyLinePlaceholder":109},[84,1390,1391,1393,1396],{"class":86,"line":161},[84,1392,1372],{"class":90},[84,1394,1395],{"class":119}," WorkGuard",[84,1397,1398],{"class":90}," =\n",[84,1400,1401,1403,1405,1407,1410],{"class":86,"line":166},[84,1402,149],{"class":119},[84,1404,152],{"class":123},[84,1406,155],{"class":119},[84,1408,1409],{"class":123},"::executor_work_guard",[84,1411,1412],{"class":90},"\u003C\n",[84,1414,1415,1418,1420,1422,1424,1426,1429,1432],{"class":86,"line":186},[84,1416,1417],{"class":119},"        boost",[84,1419,152],{"class":123},[84,1421,155],{"class":119},[84,1423,152],{"class":123},[84,1425,21],{"class":119},[84,1427,1428],{"class":123},"::executor_type",[84,1430,1431],{"class":90},">",[84,1433,259],{"class":123},[84,1435,1436],{"class":86,"line":191},[84,1437,110],{"emptyLinePlaceholder":109},[84,1439,1440,1442,1445],{"class":86,"line":197},[84,1441,394],{"class":90},[84,1443,1444],{"class":119}," delayed_post",[84,1446,1447],{"class":123},"(\n",[84,1449,1450,1452,1454,1456,1458,1460,1463,1466],{"class":86,"line":222},[84,1451,149],{"class":119},[84,1453,152],{"class":123},[84,1455,155],{"class":119},[84,1457,152],{"class":123},[84,1459,21],{"class":119},[84,1461,1462],{"class":90},"*",[84,1464,1465],{"class":416}," io",[84,1467,1468],{"class":123},",\n",[84,1470,1471,1474,1476,1479],{"class":86,"line":227},[84,1472,1473],{"class":119},"    WorkGuard",[84,1475,1462],{"class":90},[84,1477,1478],{"class":416}," guard",[84,1480,420],{"class":123},[84,1482,1483],{"class":86,"line":244},[84,1484,130],{"class":123},[84,1486,1487,1489,1491,1493,1495,1498],{"class":86,"line":249},[84,1488,169],{"class":119},[84,1490,152],{"class":123},[84,1492,174],{"class":119},[84,1494,177],{"class":123},[84,1496,1497],{"class":94},"\"工作线程：等待 2 秒再提交任务\"",[84,1499,183],{"class":123},[84,1501,1502],{"class":86,"line":262},[84,1503,110],{"emptyLinePlaceholder":109},[84,1505,1506,1508,1510,1513,1515,1518,1520,1523,1526],{"class":86,"line":505},[84,1507,169],{"class":119},[84,1509,152],{"class":123},[84,1511,1512],{"class":119},"this_thread",[84,1514,152],{"class":123},[84,1516,1517],{"class":119},"sleep_for",[84,1519,177],{"class":123},[84,1521,1522],{"class":255},"2",[84,1524,1525],{"class":90},"s",[84,1527,183],{"class":123},[84,1529,1530],{"class":86,"line":547},[84,1531,110],{"emptyLinePlaceholder":109},[84,1533,1534,1536,1538,1540,1542,1545],{"class":86,"line":552},[84,1535,169],{"class":119},[84,1537,152],{"class":123},[84,1539,174],{"class":119},[84,1541,177],{"class":123},[84,1543,1544],{"class":94},"\"工作线程：向 io_context 提交任务\"",[84,1546,183],{"class":123},[84,1548,1549],{"class":86,"line":568},[84,1550,110],{"emptyLinePlaceholder":109},[84,1552,1553,1555,1557,1559,1561,1563],{"class":86,"line":604},[84,1554,149],{"class":119},[84,1556,152],{"class":123},[84,1558,155],{"class":119},[84,1560,152],{"class":123},[84,1562,516],{"class":119},[84,1564,1447],{"class":123},[84,1566,1567,1570],{"class":86,"line":609},[84,1568,1569],{"class":90},"        *",[84,1571,1572],{"class":123},"io,\n",[84,1574,1575],{"class":86,"line":624},[84,1576,1577],{"class":123},"        [] {\n",[84,1579,1580,1583,1585,1587],{"class":86,"line":629},[84,1581,1582],{"class":119},"            std",[84,1584,152],{"class":123},[84,1586,174],{"class":119},[84,1588,1447],{"class":123},[84,1590,1591,1594],{"class":86,"line":634},[84,1592,1593],{"class":94},"                \"Asio handler：收到后来提交的任务\"",[84,1595,183],{"class":123},[84,1597,1598],{"class":86,"line":653},[84,1599,1600],{"class":123},"        });\n",[84,1602,1603],{"class":86,"line":658},[84,1604,110],{"emptyLinePlaceholder":109},[84,1606,1607,1609,1611,1613,1615,1618],{"class":86,"line":674},[84,1608,169],{"class":119},[84,1610,152],{"class":123},[84,1612,174],{"class":119},[84,1614,177],{"class":123},[84,1616,1617],{"class":94},"\"工作线程：释放 work_guard\"",[84,1619,183],{"class":123},[84,1621,1622],{"class":86,"line":679},[84,1623,110],{"emptyLinePlaceholder":109},[84,1625,1626,1629,1632],{"class":86,"line":688},[84,1627,1628],{"class":123},"    guard->",[84,1630,1631],{"class":119},"reset",[84,1633,219],{"class":123},[84,1635,1637],{"class":86,"line":1636},33,[84,1638,265],{"class":123},[84,1640,1642],{"class":86,"line":1641},34,[84,1643,110],{"emptyLinePlaceholder":109},[84,1645,1647,1649,1651],{"class":86,"line":1646},35,[84,1648,116],{"class":90},[84,1650,120],{"class":119},[84,1652,124],{"class":123},[84,1654,1656],{"class":86,"line":1655},36,[84,1657,130],{"class":123},[84,1659,1661,1663,1665,1667],{"class":86,"line":1660},37,[84,1662,149],{"class":119},[84,1664,152],{"class":123},[84,1666,155],{"class":119},[84,1668,158],{"class":123},[84,1670,1672],{"class":86,"line":1671},38,[84,1673,110],{"emptyLinePlaceholder":109},[84,1675,1677,1680],{"class":86,"line":1676},39,[84,1678,1679],{"class":123},"    WorkGuard guard ",[84,1681,1682],{"class":90},"=\n",[84,1684,1686,1688,1690,1692,1694,1696],{"class":86,"line":1685},40,[84,1687,1417],{"class":119},[84,1689,152],{"class":123},[84,1691,155],{"class":119},[84,1693,152],{"class":123},[84,1695,1204],{"class":119},[84,1697,1207],{"class":123},[84,1699,1701],{"class":86,"line":1700},41,[84,1702,110],{"emptyLinePlaceholder":109},[84,1704,1706,1708,1711,1714],{"class":86,"line":1705},42,[84,1707,169],{"class":119},[84,1709,1710],{"class":123},"::thread ",[84,1712,1713],{"class":119},"worker",[84,1715,1447],{"class":123},[84,1717,1719,1722,1724,1726],{"class":86,"line":1718},43,[84,1720,1721],{"class":119},"        std",[84,1723,152],{"class":123},[84,1725,527],{"class":119},[84,1727,1447],{"class":123},[84,1729,1731],{"class":86,"line":1730},44,[84,1732,1733],{"class":123},"            delayed_post,\n",[84,1735,1737,1740],{"class":86,"line":1736},45,[84,1738,1739],{"class":90},"            &",[84,1741,1572],{"class":123},[84,1743,1745,1747],{"class":86,"line":1744},46,[84,1746,1739],{"class":90},[84,1748,1749],{"class":123},"guard));\n",[84,1751,1753],{"class":86,"line":1752},47,[84,1754,110],{"emptyLinePlaceholder":109},[84,1756,1758,1760,1762,1764,1766,1769],{"class":86,"line":1757},48,[84,1759,169],{"class":119},[84,1761,152],{"class":123},[84,1763,174],{"class":119},[84,1765,177],{"class":123},[84,1767,1768],{"class":94},"\"main：开始 io.run()\"",[84,1770,183],{"class":123},[84,1772,1774],{"class":86,"line":1773},49,[84,1775,110],{"emptyLinePlaceholder":109},[84,1777,1779,1781,1783,1785,1787,1789,1791,1793],{"class":86,"line":1778},50,[84,1780,169],{"class":119},[84,1782,152],{"class":123},[84,1784,204],{"class":90},[84,1786,207],{"class":123},[84,1788,210],{"class":90},[84,1790,213],{"class":123},[84,1792,216],{"class":119},[84,1794,219],{"class":123},[84,1796,1798],{"class":86,"line":1797},51,[84,1799,110],{"emptyLinePlaceholder":109},[84,1801,1803,1805,1807,1809],{"class":86,"line":1802},52,[84,1804,169],{"class":119},[84,1806,152],{"class":123},[84,1808,174],{"class":119},[84,1810,1447],{"class":123},[84,1812,1814,1817],{"class":86,"line":1813},53,[84,1815,1816],{"class":94},"        \"main：io.run() 返回，执行了 {} 个 handler\"",[84,1818,1468],{"class":123},[84,1820,1822],{"class":86,"line":1821},54,[84,1823,1824],{"class":123},"        count);\n",[84,1826,1828],{"class":86,"line":1827},55,[84,1829,110],{"emptyLinePlaceholder":109},[84,1831,1833,1836,1839],{"class":86,"line":1832},56,[84,1834,1835],{"class":123},"    worker.",[84,1837,1838],{"class":119},"join",[84,1840,219],{"class":123},[84,1842,1844],{"class":86,"line":1843},57,[84,1845,110],{"emptyLinePlaceholder":109},[84,1847,1849,1851,1853],{"class":86,"line":1848},58,[84,1850,252],{"class":90},[84,1852,256],{"class":255},[84,1854,259],{"class":123},[84,1856,1858],{"class":86,"line":1857},59,[84,1859,265],{"class":123},[15,1861,1862],{},"运行结果大致为：",[75,1864,1867],{"className":1865,"code":1866,"language":284,"meta":80},[282],"main：开始 io.run()\n工作线程：等待 2 秒再提交任务\n\n工作线程：向 io_context 提交任务\n工作线程：释放 work_guard\nAsio handler：收到后来提交的任务\n\nmain：io.run() 返回，执行了 1 个 handler\n",[19,1868,1866],{"__ignoreMap":80},[15,1870,1871],{},"具体打印先后可能因为线程调度略有变化，但核心流程不变。",[44,1873],{},[58,1875,1876],{"id":1876},"整个执行过程",[15,1878,1879],{},"程序首先创建：",[75,1881,1883],{"className":77,"code":1882,"language":79,"meta":80,"style":80},"boost::asio::io_context io;\n",[19,1884,1885],{"__ignoreMap":80},[84,1886,1887,1889,1891,1893],{"class":86,"line":87},[84,1888,750],{"class":119},[84,1890,152],{"class":123},[84,1892,155],{"class":119},[84,1894,158],{"class":123},[15,1896,1047],{},[75,1898,1901],{"className":1899,"code":1900,"language":284,"meta":80},[282],"io_context\n↓\n没有任何任务\n",[19,1902,1900],{"__ignoreMap":80},[15,1904,1905],{},"然后：",[75,1907,1909],{"className":77,"code":1908,"language":79,"meta":80,"style":80},"WorkGuard guard =\n    boost::asio::make_work_guard(io);\n",[19,1910,1911,1918],{"__ignoreMap":80},[84,1912,1913,1916],{"class":86,"line":87},[84,1914,1915],{"class":123},"WorkGuard guard ",[84,1917,1682],{"class":90},[84,1919,1920,1922,1924,1926,1928,1930],{"class":86,"line":98},[84,1921,149],{"class":119},[84,1923,152],{"class":123},[84,1925,155],{"class":119},[84,1927,152],{"class":123},[84,1929,1204],{"class":119},[84,1931,1207],{"class":123},[15,1933,1934,1935,1937],{},"相当于告诉 ",[19,1936,21],{},"：",[75,1939,1942],{"className":1940,"code":1941,"language":284,"meta":80},[282],"虽然现在可能没有任务，\n\n但先不要认为整个事件循环已经结束，\n\n以后还可能有人给你提交工作。\n",[19,1943,1941],{"__ignoreMap":80},[15,1945,1946],{},"接着启动：",[75,1948,1950],{"className":77,"code":1949,"language":79,"meta":80,"style":80},"std::thread worker(...);\n",[19,1951,1952],{"__ignoreMap":80},[84,1953,1954,1956,1958,1961,1964],{"class":86,"line":87},[84,1955,522],{"class":119},[84,1957,152],{"class":123},[84,1959,1960],{"class":119},"thread",[84,1962,1963],{"class":119}," worker",[84,1965,1119],{"class":123},[15,1967,1968],{},"这个线程会先：",[75,1970,1972],{"className":77,"code":1971,"language":79,"meta":80,"style":80},"std::this_thread::sleep_for(2s);\n",[19,1973,1974],{"__ignoreMap":80},[84,1975,1976,1978,1980,1982,1984,1986,1988,1990,1992],{"class":86,"line":87},[84,1977,522],{"class":119},[84,1979,152],{"class":123},[84,1981,1512],{"class":119},[84,1983,152],{"class":123},[84,1985,1517],{"class":119},[84,1987,177],{"class":123},[84,1989,1522],{"class":255},[84,1991,1525],{"class":90},[84,1993,183],{"class":123},[15,1995,1996,1997,1999],{},"所以刚开始的时候，",[19,1998,21],{}," 里面其实真的没有任何 handler 可以执行。",[15,2001,2002],{},"此时 main 执行：",[75,2004,2005],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,2006,2007],{"__ignoreMap":80},[84,2008,2009,2011,2013],{"class":86,"line":87},[84,2010,730],{"class":123},[84,2012,216],{"class":119},[84,2014,219],{"class":123},[15,2016,2017],{},"如果没有 guard，逻辑会变成：",[75,2019,2022],{"className":2020,"code":2021,"language":284,"meta":80},[282],"io.run()\n↓\n当前没有任何工作\n↓\n立即返回\n",[19,2023,2021],{"__ignoreMap":80},[15,2025,2026],{},"但现在有 guard：",[75,2028,2031],{"className":2029,"code":2030,"language":284,"meta":80},[282],"io.run()\n↓\n当前没有 handler\n↓\n但是 work_guard 仍然有效\n↓\n说明仍然存在 outstanding work\n↓\n不能退出\n↓\n继续阻塞等待\n",[19,2032,2030],{"__ignoreMap":80},[15,2034,2035],{},"于是 main 就停在：",[75,2037,2038],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,2039,2040],{"__ignoreMap":80},[84,2041,2042,2044,2046],{"class":86,"line":87},[84,2043,730],{"class":123},[84,2045,216],{"class":119},[84,2047,219],{"class":123},[15,2049,2050],{},"里面等待。",[44,2052],{},[58,2054,2056],{"id":2055},"_2-秒以后发生什么","2 秒以后发生什么",[15,2058,2059],{},"worker 睡眠结束：",[75,2061,2062],{"className":77,"code":1971,"language":79,"meta":80,"style":80},[19,2063,2064],{"__ignoreMap":80},[84,2065,2066,2068,2070,2072,2074,2076,2078,2080,2082],{"class":86,"line":87},[84,2067,522],{"class":119},[84,2069,152],{"class":123},[84,2071,1512],{"class":119},[84,2073,152],{"class":123},[84,2075,1517],{"class":119},[84,2077,177],{"class":123},[84,2079,1522],{"class":255},[84,2081,1525],{"class":90},[84,2083,183],{"class":123},[15,2085,2086],{},"然后执行：",[75,2088,2090],{"className":77,"code":2089,"language":79,"meta":80,"style":80},"boost::asio::post(\n    *io,\n    [] {\n        std::println(\n            \"Asio handler：收到后来提交的任务\");\n    });\n",[19,2091,2092,2106,2113,2118,2128,2135],{"__ignoreMap":80},[84,2093,2094,2096,2098,2100,2102,2104],{"class":86,"line":87},[84,2095,750],{"class":119},[84,2097,152],{"class":123},[84,2099,155],{"class":119},[84,2101,152],{"class":123},[84,2103,516],{"class":119},[84,2105,1447],{"class":123},[84,2107,2108,2111],{"class":86,"line":98},[84,2109,2110],{"class":90},"    *",[84,2112,1572],{"class":123},[84,2114,2115],{"class":86,"line":106},[84,2116,2117],{"class":123},"    [] {\n",[84,2119,2120,2122,2124,2126],{"class":86,"line":113},[84,2121,1721],{"class":119},[84,2123,152],{"class":123},[84,2125,174],{"class":119},[84,2127,1447],{"class":123},[84,2129,2130,2133],{"class":86,"line":127},[84,2131,2132],{"class":94},"            \"Asio handler：收到后来提交的任务\"",[84,2134,183],{"class":123},[84,2136,2137],{"class":86,"line":133},[84,2138,2139],{"class":123},"    });\n",[15,2141,2142,2144],{},[19,2143,28],{}," 相当于：",[12,2146,2147],{},[15,2148,2149],{},[269,2150,2151,2152,2154],{},"向 ",[19,2153,21],{}," 投递一个以后要执行的 handler。",[15,2156,2157],{},"于是原本正在：",[75,2159,2162],{"className":2160,"code":2161,"language":284,"meta":80},[282],"阻塞等待\n",[19,2163,2161],{"__ignoreMap":80},[15,2165,2166,2167,875],{},"的 ",[19,2168,69],{},[75,2170,2173],{"className":2171,"code":2172,"language":284,"meta":80},[282],"有新任务来了\n",[19,2174,2172],{"__ignoreMap":80},[15,2176,2177],{},"然后执行这个 handler。",[44,2179],{},[58,2181,2183,2186],{"id":2182},"guardreset-到底做什么",[19,2184,2185],{},"guard.reset()"," 到底做什么",[15,2188,2189],{},"接下来：",[75,2191,2193],{"className":77,"code":2192,"language":79,"meta":80,"style":80},"guard->reset();\n",[19,2194,2195],{"__ignoreMap":80},[84,2196,2197,2200,2202],{"class":86,"line":87},[84,2198,2199],{"class":123},"guard->",[84,2201,1631],{"class":119},[84,2203,219],{"class":123},[15,2205,2206],{},"它并不是：",[75,2208,2211],{"className":2209,"code":2210,"language":284,"meta":80},[282],"停止 io_context\n",[19,2212,2210],{"__ignoreMap":80},[15,2214,2215],{},"也不是：",[75,2217,2220],{"className":2218,"code":2219,"language":284,"meta":80},[282],"取消所有任务\n",[19,2221,2219],{"__ignoreMap":80},[15,2223,2224],{},"更不是：",[75,2226,2229],{"className":2227,"code":2228,"language":284,"meta":80},[282],"让 run() 立刻强制返回\n",[19,2230,2228],{"__ignoreMap":80},[15,2232,2233],{},"它真正表达的是：",[12,2235,2236],{},[15,2237,2238],{},[269,2239,2240,2241,2243],{},"我之前登记的那份“占位工作”现在结束了，你以后不用再为了我强行保持 ",[19,2242,25],{}," 存活。",[15,2245,2246],{},"可以粗略理解成：",[75,2248,2251],{"className":2249,"code":2250,"language":284,"meta":80},[282],"创建 guard\n\noutstanding work：\n+1\n",[19,2252,2250],{"__ignoreMap":80},[15,2254,1905],{},[75,2256,2259],{"className":2257,"code":2258,"language":284,"meta":80},[282],"guard.reset()\n\noutstanding work：\n-1\n",[19,2260,2258],{"__ignoreMap":80},[15,2262,2263,2264,2266],{},"于是 ",[19,2265,21],{}," 又恢复正常退出规则：",[75,2268,2271],{"className":2269,"code":2270,"language":284,"meta":80},[282],"如果还有真正的任务\n→ 继续处理\n\n如果还有未完成异步操作\n→ 继续等待\n\n如果什么都没有了\n→ run() 可以返回\n",[19,2272,2270],{"__ignoreMap":80},[15,2274,1056],{},[75,2276,2278],{"className":77,"code":2277,"language":79,"meta":80,"style":80},"guard.reset();\n",[19,2279,2280],{"__ignoreMap":80},[84,2281,2282,2285,2287],{"class":86,"line":87},[84,2283,2284],{"class":123},"guard.",[84,2286,1631],{"class":119},[84,2288,219],{"class":123},[15,2290,2291],{},"不是：",[75,2293,2296],{"className":2294,"code":2295,"language":284,"meta":80},[282],"命令 run() 退出\n",[19,2297,2295],{"__ignoreMap":80},[15,2299,2300],{},"而是：",[75,2302,2305],{"className":2303,"code":2304,"language":284,"meta":80},[282],"取消“禁止 run() 因没工作而退出”这个限制\n",[19,2306,2304],{"__ignoreMap":80},[15,2308,2309],{},"这一点非常重要。",[44,2311],{},[58,2313,2315],{"id":2314},"为什么-post-以后再-reset","为什么 post 以后再 reset",[15,2317,2318],{},"本例中：",[75,2320,2322],{"className":77,"code":2321,"language":79,"meta":80,"style":80},"boost::asio::post(*io, handler);\n\nguard->reset();\n",[19,2323,2324,2343,2347],{"__ignoreMap":80},[84,2325,2326,2328,2330,2332,2334,2336,2338,2340],{"class":86,"line":87},[84,2327,750],{"class":119},[84,2329,152],{"class":123},[84,2331,155],{"class":119},[84,2333,152],{"class":123},[84,2335,516],{"class":119},[84,2337,177],{"class":123},[84,2339,1462],{"class":90},[84,2341,2342],{"class":123},"io, handler);\n",[84,2344,2345],{"class":86,"line":98},[84,2346,110],{"emptyLinePlaceholder":109},[84,2348,2349,2351,2353],{"class":86,"line":106},[84,2350,2199],{"class":123},[84,2352,1631],{"class":119},[84,2354,219],{"class":123},[15,2356,2357],{},"顺序可以理解成：",[75,2359,2362],{"className":2360,"code":2361,"language":284,"meta":80},[282],"先把真正的工作提交进去\n↓\n然后取消 guard 的占位工作\n",[19,2363,2361],{"__ignoreMap":80},[15,2365,2366,2367,2369],{},"这时 ",[19,2368,21],{}," 中仍然还有：",[75,2371,2374],{"className":2372,"code":2373,"language":284,"meta":80},[282],"刚刚 post 的 handler\n",[19,2375,2373],{"__ignoreMap":80},[15,2377,2378],{},"所以即使 guard 被 reset：",[75,2380,2383],{"className":2381,"code":2382,"language":284,"meta":80},[282],"还有真正工作\n↓\nrun() 继续\n↓\n执行 handler\n↓\nhandler 执行结束\n↓\n此时已经没有其他工作\n↓\nrun() 返回\n",[19,2384,2382],{"__ignoreMap":80},[15,2386,2387],{},"完整过程：",[75,2389,2392],{"className":2390,"code":2391,"language":284,"meta":80},[282],"创建 io_context\n│\n├─ 当前没有任务\n│\n↓\n创建 work_guard\n│\n├─ 人为保持 outstanding work\n│\n↓\nmain：io.run()\n│\n├─ 当前没 handler\n│\n├─ 但 guard 还在\n│\n└─ 所以阻塞等待，不退出\n│\n│\n│       worker 睡眠 2 秒\n│\n│               ↓\n│       post(handler)\n│               ↓\n│       guard.reset()\n│\n↓\nio.run() 收到 handler\n│\n↓\n执行 handler\n│\n↓\nhandler 完成\n│\n├─ guard 已 reset\n├─ 没有其他任务\n├─ 没有未完成异步操作\n│\n↓\nio.run() 返回\n",[19,2393,2391],{"__ignoreMap":80},[15,2395,2396,2397,2399],{},"这就是 ",[19,2398,31],{}," 的完整作用。",[44,2401],{},[58,2403,2405,2406,2409],{"id":2404},"如果一直不-reset-会怎样","如果一直不 ",[19,2407,2408],{},"reset()"," 会怎样",[15,2411,2412],{},"假设：",[75,2414,2416],{"className":77,"code":2415,"language":79,"meta":80,"style":80},"WorkGuard guard =\n    boost::asio::make_work_guard(io);\n\nio.run();\n",[19,2417,2418,2424,2438,2442],{"__ignoreMap":80},[84,2419,2420,2422],{"class":86,"line":87},[84,2421,1915],{"class":123},[84,2423,1682],{"class":90},[84,2425,2426,2428,2430,2432,2434,2436],{"class":86,"line":98},[84,2427,149],{"class":119},[84,2429,152],{"class":123},[84,2431,155],{"class":119},[84,2433,152],{"class":123},[84,2435,1204],{"class":119},[84,2437,1207],{"class":123},[84,2439,2440],{"class":86,"line":106},[84,2441,110],{"emptyLinePlaceholder":109},[84,2443,2444,2446,2448],{"class":86,"line":113},[84,2445,730],{"class":123},[84,2447,216],{"class":119},[84,2449,219],{"class":123},[15,2451,2452],{},"又永远不：",[75,2454,2455],{"className":77,"code":2277,"language":79,"meta":80,"style":80},[19,2456,2457],{"__ignoreMap":80},[84,2458,2459,2461,2463],{"class":86,"line":87},[84,2460,2284],{"class":123},[84,2462,1631],{"class":119},[84,2464,219],{"class":123},[15,2466,2467],{},"那么即使所有真正任务都已经执行完：",[75,2469,2472],{"className":2470,"code":2471,"language":284,"meta":80},[282],"handler 全执行完了\n\ntimer 全结束了\n\nsocket 也没任务了\n",[19,2473,2471],{"__ignoreMap":80},[15,2475,2476,2478],{},[19,2477,69],{}," 仍然会认为：",[75,2480,2483],{"className":2481,"code":2482,"language":284,"meta":80},[282],"还有一份 outstanding work\n",[19,2484,2482],{"__ignoreMap":80},[15,2486,1056],{},[75,2488,2491],{"className":2489,"code":2490,"language":284,"meta":80},[282],"不会正常返回\n",[19,2492,2490],{"__ignoreMap":80},[15,2494,2495],{},"它会继续等待以后可能到来的任务。",[15,2497,2498],{},"这正是后台 Asio 线程经常需要的效果。",[44,2500],{},[58,2502,2504,2506,2507,2510],{"id":2503},"reset-和-iostop-不一样",[19,2505,2408],{}," 和 ",[19,2508,2509],{},"io.stop()"," 不一样",[15,2512,2513],{},"这两个很容易混。",[15,2515,2516,2518],{},[19,2517,2185],{}," 的意思是：",[12,2520,2521],{},[15,2522,2523],{},[269,2524,2525,2526,2528],{},"允许 ",[19,2527,69],{}," 在所有真正工作完成以后自然退出。",[15,2530,2531],{},"也就是：",[75,2533,2536],{"className":2534,"code":2535,"language":284,"meta":80},[282],"reset()\n↓\n不再人为保持 io_context 存活\n↓\n还有任务就继续执行\n↓\n任务全部完成后 run() 自然返回\n",[19,2537,2535],{"__ignoreMap":80},[15,2539,2540],{},"而：",[75,2542,2544],{"className":77,"code":2543,"language":79,"meta":80,"style":80},"io.stop();\n",[19,2545,2546],{"__ignoreMap":80},[84,2547,2548,2550,2553],{"class":86,"line":87},[84,2549,730],{"class":123},[84,2551,2552],{"class":119},"stop",[84,2554,219],{"class":123},[15,2556,2557],{},"更像：",[12,2559,2560],{},[15,2561,2562],{},[269,2563,2564,2565,2567],{},"要求这个 ",[19,2566,21],{}," 尽快停止运行。",[15,2569,2570],{},"所以简单理解：",[75,2572,2575],{"className":2573,"code":2574,"language":284,"meta":80},[282],"guard.reset()\n\n→ 我不再拦着你退出\n→ 剩余工作正常处理\n→ 没工作以后自然退出\n",[19,2576,2574],{"__ignoreMap":80},[15,2578,2540],{},[75,2580,2583],{"className":2581,"code":2582,"language":284,"meta":80},[282],"io.stop()\n\n→ 主动要求事件循环停止\n",[19,2584,2582],{"__ignoreMap":80},[15,2586,2587],{},"因此如果希望：",[75,2589,2592],{"className":2590,"code":2591,"language":284,"meta":80},[282],"尽量优雅地把已经提交的任务处理完再退出\n",[19,2593,2591],{"__ignoreMap":80},[15,2595,2596],{},"通常更关注：",[75,2598,2599],{"className":77,"code":2277,"language":79,"meta":80,"style":80},[19,2600,2601],{"__ignoreMap":80},[84,2602,2603,2605,2607],{"class":86,"line":87},[84,2604,2284],{"class":123},[84,2606,1631],{"class":119},[84,2608,219],{"class":123},[15,2610,2611],{},"如果希望主动让事件循环停止，则可以使用：",[75,2613,2614],{"className":77,"code":2543,"language":79,"meta":80,"style":80},[19,2615,2616],{"__ignoreMap":80},[84,2617,2618,2620,2622],{"class":86,"line":87},[84,2619,730],{"class":123},[84,2621,2552],{"class":119},[84,2623,219],{"class":123},[44,2625],{},[58,2627,2629],{"id":2628},"机器人程序中为什么经常需要-work_guard","机器人程序中为什么经常需要 work_guard",[15,2631,2632],{},"例如你的程序可能是：",[75,2634,2637],{"className":2635,"code":2636,"language":284,"meta":80},[282],"main\n│\n├─ 创建 io_context\n│\n├─ 创建串口驱动\n│\n├─ 创建 Asio 通信线程\n│\n└─ ROS2 开始运行\n",[19,2638,2636],{"__ignoreMap":80},[15,2640,2641],{},"Asio 通信线程：",[75,2643,2644],{"className":77,"code":723,"language":79,"meta":80,"style":80},[19,2645,2646],{"__ignoreMap":80},[84,2647,2648,2650,2652],{"class":86,"line":87},[84,2649,730],{"class":123},[84,2651,216],{"class":119},[84,2653,219],{"class":123},[15,2655,2656],{},"而真正的异步任务可能是之后才出现：",[75,2658,2661],{"className":2659,"code":2660,"language":284,"meta":80},[282],"ROS2 callback\n↓\n要求发送串口命令\n↓\npost 到 io_context\n\n或者\n\n设备稍后连接\n↓\n启动 async_read\n\n或者\n\n以后动态创建 timer\n",[19,2662,2660],{"__ignoreMap":80},[15,2664,2665],{},"如果 Asio 线程刚启动时：",[75,2667,2670],{"className":2668,"code":2669,"language":284,"meta":80},[282],"暂时没有任何 outstanding work\n",[19,2671,2669],{"__ignoreMap":80},[15,2673,2674],{},"那么没有 guard：",[75,2676,2679],{"className":2677,"code":2678,"language":284,"meta":80},[282],"Asio 线程\n↓\nio.run()\n↓\n没任务\n↓\n直接返回\n↓\n通信线程死掉\n",[19,2680,2678],{"__ignoreMap":80},[15,2682,2683],{},"使用 guard：",[75,2685,2688],{"className":2686,"code":2687,"language":284,"meta":80},[282],"Asio 线程\n↓\nio.run()\n↓\n暂时没任务\n↓\nguard 还在\n↓\n继续等待\n↓\n以后任务来了\n↓\n正常处理\n",[19,2689,2687],{"__ignoreMap":80},[15,2691,2692,2693,2695],{},"因此可以把 ",[19,2694,31],{}," 理解成：",[12,2697,2698],{},[15,2699,2700],{},[269,2701,2702],{},"给长期运行的 Asio 事件循环办理了一张“先别下班”的凭证。",[44,2704],{},[58,2706,2708,2506,2711,2713],{"id":2707},"make_work_guard-和-reset-怎么记",[19,2709,2710],{},"make_work_guard()",[19,2712,2408],{}," 怎么记",[15,2715,1177],{},[75,2717,2719],{"className":77,"code":2718,"language":79,"meta":80,"style":80},"auto guard =\n    boost::asio::make_work_guard(io);\n",[19,2720,2721,2729],{"__ignoreMap":80},[84,2722,2723,2725,2727],{"class":86,"line":87},[84,2724,1187],{"class":90},[84,2726,1190],{"class":123},[84,2728,1682],{"class":90},[84,2730,2731,2733,2735,2737,2739,2741],{"class":86,"line":98},[84,2732,149],{"class":119},[84,2734,152],{"class":123},[84,2736,155],{"class":119},[84,2738,152],{"class":123},[84,2740,1204],{"class":119},[84,2742,1207],{"class":123},[15,2744,2745],{},"可以理解成：",[75,2747,2750],{"className":2748,"code":2749,"language":284,"meta":80},[282],"告诉 io_context：\n\n“我这里还有未来工作，\n即使眼前没任务，你也先别让 run() 下班。”\n",[19,2751,2749],{"__ignoreMap":80},[15,2753,2754],{},"释放：",[75,2756,2757],{"className":77,"code":2277,"language":79,"meta":80,"style":80},[19,2758,2759],{"__ignoreMap":80},[84,2760,2761,2763,2765],{"class":86,"line":87},[84,2762,2284],{"class":123},[84,2764,1631],{"class":119},[84,2766,219],{"class":123},[15,2768,2745],{},[75,2770,2773],{"className":2771,"code":2772,"language":284,"meta":80},[282],"告诉 io_context：\n\n“我这边以后不会再依赖你继续保持运行了，\n如果其他工作也都结束了，你可以让 run() 返回。”\n",[19,2774,2772],{"__ignoreMap":80},[15,2776,2777],{},"所以它们不是：",[75,2779,2782],{"className":2780,"code":2781,"language":284,"meta":80},[282],"make_work_guard()\n→ 创建一个实际任务\n\nreset()\n→ 删除一个实际任务\n",[19,2783,2781],{"__ignoreMap":80},[15,2785,2300],{},[75,2787,2790],{"className":2788,"code":2789,"language":284,"meta":80},[282],"make_work_guard()\n→ 持有一份 outstanding work\n\nreset()\n→ 放弃这份 outstanding work\n",[19,2791,2789],{"__ignoreMap":80},[44,2793],{},[58,2795,2796],{"id":2796},"本示例最重要的结论",[15,2798,2799,2800,1937],{},"没有 ",[19,2801,31],{},[75,2803,2806],{"className":2804,"code":2805,"language":284,"meta":80},[282],"io.run()\n↓\n暂时没有工作\n↓\n直接返回\n",[19,2807,2805],{"__ignoreMap":80},[15,2809,2810,2811,1937],{},"有 ",[19,2812,31],{},[75,2814,2817],{"className":2815,"code":2816,"language":284,"meta":80},[282],"io.run()\n↓\n暂时没有工作\n↓\n但 guard 仍持有 outstanding work\n↓\n继续阻塞等待未来任务\n",[19,2818,2816],{"__ignoreMap":80},[15,2820,2821],{},"释放 guard：",[75,2823,2826],{"className":2824,"code":2825,"language":284,"meta":80},[282],"guard.reset()\n↓\n不再人为维持 io_context 存活\n↓\n如果真正工作也全部结束\n↓\nio.run() 返回\n",[19,2827,2825],{"__ignoreMap":80},[15,2829,2830],{},"所以一句话记住：",[12,2832,2833],{},[15,2834,2835],{},[269,2836,2837,2839,2840,2842],{},[19,2838,31],{}," 不是一个真正要执行的任务，而是一份“还有工作存在”的占位声明，用来防止 ",[19,2841,69],{}," 在暂时无任务时提前返回。",[44,2844],{},[47,2846,2848,2849,2851],{"id":2847},"示例-4buffer-的基本使用","示例 4：",[19,2850,34],{}," 的基本使用",[58,2853,60],{"id":2854},"程序目标-3",[15,2856,2857],{},"Boost.Asio 读写数据时经常写：",[75,2859,2861],{"className":77,"code":2860,"language":79,"meta":80,"style":80},"boost::asio::buffer(data)\n",[19,2862,2863],{"__ignoreMap":80},[84,2864,2865,2867,2869,2871,2873,2875],{"class":86,"line":87},[84,2866,750],{"class":119},[84,2868,152],{"class":123},[84,2870,155],{"class":119},[84,2872,152],{"class":123},[84,2874,34],{"class":119},[84,2876,2877],{"class":123},"(data)\n",[15,2879,2880],{},"本例先看它的基本含义。",[58,2882,73],{"id":2883},"完整代码-3",[75,2885,2887],{"className":77,"code":2886,"language":79,"meta":80,"style":80},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Carray>\n#include \u003Cprint>\n#include \u003Cstring>\n\nint main()\n{\n    \u002F\u002F 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    std::string msg = \"hello asio\";\n    auto buf1 = boost::asio::buffer(msg);\n\n    \u002F\u002F std::array 是固定长度数组，长度在编译期就确定。\n    std::array\u003Cchar, 128> data;\n    auto buf2 = boost::asio::buffer(data);\n\n    std::println(\"msg.size() = {}\", msg.size());\n    std::println(\"buffer(msg).size() = {}\", buf1.size());\n    std::println(\"array size = {}\", data.size());\n    std::println(\"buffer(data).size() = {}\", buf2.size());\n\n    return 0;\n}\n",[19,2888,2889,2895,2902,2908,2914,2918,2926,2930,2934,2948,2971,2975,2980,3001,3023,3027,3049,3069,3089,3109,3113,3121],{"__ignoreMap":80},[84,2890,2891,2893],{"class":86,"line":87},[84,2892,91],{"class":90},[84,2894,95],{"class":94},[84,2896,2897,2899],{"class":86,"line":98},[84,2898,91],{"class":90},[84,2900,2901],{"class":94}," \u003Carray>\n",[84,2903,2904,2906],{"class":86,"line":106},[84,2905,91],{"class":90},[84,2907,103],{"class":94},[84,2909,2910,2912],{"class":86,"line":113},[84,2911,91],{"class":90},[84,2913,385],{"class":94},[84,2915,2916],{"class":86,"line":127},[84,2917,110],{"emptyLinePlaceholder":109},[84,2919,2920,2922,2924],{"class":86,"line":133},[84,2921,116],{"class":90},[84,2923,120],{"class":119},[84,2925,124],{"class":123},[84,2927,2928],{"class":86,"line":140},[84,2929,130],{"class":123},[84,2931,2932],{"class":86,"line":146},[84,2933,137],{"class":136},[84,2935,2936,2938,2941,2943,2946],{"class":86,"line":161},[84,2937,169],{"class":119},[84,2939,2940],{"class":123},"::string msg ",[84,2942,210],{"class":90},[84,2944,2945],{"class":94}," \"hello asio\"",[84,2947,259],{"class":123},[84,2949,2950,2953,2956,2958,2960,2962,2964,2966,2968],{"class":86,"line":166},[84,2951,2952],{"class":90},"    auto",[84,2954,2955],{"class":123}," buf1 ",[84,2957,210],{"class":90},[84,2959,1195],{"class":119},[84,2961,152],{"class":123},[84,2963,155],{"class":119},[84,2965,152],{"class":123},[84,2967,34],{"class":119},[84,2969,2970],{"class":123},"(msg);\n",[84,2972,2973],{"class":86,"line":186},[84,2974,110],{"emptyLinePlaceholder":109},[84,2976,2977],{"class":86,"line":191},[84,2978,2979],{"class":136},"    \u002F\u002F std::array 是固定长度数组，长度在编译期就确定。\n",[84,2981,2982,2984,2987,2990,2993,2996,2998],{"class":86,"line":197},[84,2983,169],{"class":119},[84,2985,2986],{"class":123},"::array",[84,2988,2989],{"class":90},"\u003Cchar",[84,2991,2992],{"class":123},", ",[84,2994,2995],{"class":255},"128",[84,2997,1431],{"class":90},[84,2999,3000],{"class":123}," data;\n",[84,3002,3003,3005,3008,3010,3012,3014,3016,3018,3020],{"class":86,"line":222},[84,3004,2952],{"class":90},[84,3006,3007],{"class":123}," buf2 ",[84,3009,210],{"class":90},[84,3011,1195],{"class":119},[84,3013,152],{"class":123},[84,3015,155],{"class":119},[84,3017,152],{"class":123},[84,3019,34],{"class":119},[84,3021,3022],{"class":123},"(data);\n",[84,3024,3025],{"class":86,"line":227},[84,3026,110],{"emptyLinePlaceholder":109},[84,3028,3029,3031,3033,3035,3037,3040,3043,3046],{"class":86,"line":244},[84,3030,169],{"class":119},[84,3032,152],{"class":123},[84,3034,174],{"class":119},[84,3036,177],{"class":123},[84,3038,3039],{"class":94},"\"msg.size() = {}\"",[84,3041,3042],{"class":123},", msg.",[84,3044,3045],{"class":119},"size",[84,3047,3048],{"class":123},"());\n",[84,3050,3051,3053,3055,3057,3059,3062,3065,3067],{"class":86,"line":249},[84,3052,169],{"class":119},[84,3054,152],{"class":123},[84,3056,174],{"class":119},[84,3058,177],{"class":123},[84,3060,3061],{"class":94},"\"buffer(msg).size() = {}\"",[84,3063,3064],{"class":123},", buf1.",[84,3066,3045],{"class":119},[84,3068,3048],{"class":123},[84,3070,3071,3073,3075,3077,3079,3082,3085,3087],{"class":86,"line":262},[84,3072,169],{"class":119},[84,3074,152],{"class":123},[84,3076,174],{"class":119},[84,3078,177],{"class":123},[84,3080,3081],{"class":94},"\"array size = {}\"",[84,3083,3084],{"class":123},", data.",[84,3086,3045],{"class":119},[84,3088,3048],{"class":123},[84,3090,3091,3093,3095,3097,3099,3102,3105,3107],{"class":86,"line":505},[84,3092,169],{"class":119},[84,3094,152],{"class":123},[84,3096,174],{"class":119},[84,3098,177],{"class":123},[84,3100,3101],{"class":94},"\"buffer(data).size() = {}\"",[84,3103,3104],{"class":123},", buf2.",[84,3106,3045],{"class":119},[84,3108,3048],{"class":123},[84,3110,3111],{"class":86,"line":547},[84,3112,110],{"emptyLinePlaceholder":109},[84,3114,3115,3117,3119],{"class":86,"line":552},[84,3116,252],{"class":90},[84,3118,256],{"class":255},[84,3120,259],{"class":123},[84,3122,3123],{"class":86,"line":568},[84,3124,265],{"class":123},[15,3126,3127,272],{},[269,3128,271],{},[58,3130,3131],{"id":3131},"运行输出",[75,3133,3136],{"className":3134,"code":3135,"language":284,"meta":80},[282],"msg.size() = 10\nbuffer(msg).size() = 10\narray size = 128\nbuffer(data).size() = 128\n",[19,3137,3135],{"__ignoreMap":80},[58,3139,289],{"id":3140},"本示例需要注意的点-2",[15,3142,3143,3146],{},[19,3144,3145],{},"boost::asio::buffer()"," 通常不会复制数据，它只是生成一个“指向已有内存的 buffer 视图”。",[15,3148,3149],{},"所以异步读写时特别注意：",[75,3151,3154],{"className":3152,"code":3153,"language":284,"meta":80},[282],"buffer 指向的原始数据必须活到异步回调完成。\n",[19,3155,3153],{"__ignoreMap":80},[15,3157,3158],{},"错误写法示意：",[75,3160,3162],{"className":77,"code":3161,"language":79,"meta":80,"style":80},"void send()\n{\n    std::string msg = \"hello\";\n    boost::asio::async_write(socket_, boost::asio::buffer(msg), handler);\n}\n",[19,3163,3164,3173,3177,3190,3219],{"__ignoreMap":80},[84,3165,3166,3168,3171],{"class":86,"line":87},[84,3167,394],{"class":90},[84,3169,3170],{"class":119}," send",[84,3172,124],{"class":123},[84,3174,3175],{"class":86,"line":98},[84,3176,130],{"class":123},[84,3178,3179,3181,3183,3185,3188],{"class":86,"line":106},[84,3180,169],{"class":119},[84,3182,2940],{"class":123},[84,3184,210],{"class":90},[84,3186,3187],{"class":94}," \"hello\"",[84,3189,259],{"class":123},[84,3191,3192,3194,3196,3198,3200,3203,3206,3208,3210,3212,3214,3216],{"class":86,"line":113},[84,3193,149],{"class":119},[84,3195,152],{"class":123},[84,3197,155],{"class":119},[84,3199,152],{"class":123},[84,3201,3202],{"class":119},"async_write",[84,3204,3205],{"class":123},"(socket_, ",[84,3207,750],{"class":119},[84,3209,152],{"class":123},[84,3211,155],{"class":119},[84,3213,152],{"class":123},[84,3215,34],{"class":119},[84,3217,3218],{"class":123},"(msg), handler);\n",[84,3220,3221],{"class":86,"line":127},[84,3222,265],{"class":123},[15,3224,3225,3226,3229,3230,3233],{},"这个 ",[19,3227,3228],{},"msg"," 在 ",[19,3231,3232],{},"send()"," 返回后就销毁了，但异步写可能还没完成。",[15,3235,3236],{},"正确思路：",[75,3238,3241],{"className":3239,"code":3240,"language":284,"meta":80},[282],"把 msg 做成类成员变量\n或者用 shared_ptr 管理\n或者使用写队列保存待发送数据\n",[19,3242,3240],{"__ignoreMap":80},[58,3244,3246,3248],{"id":3245},"boostasiobuffer-可以接收哪些类型",[19,3247,3145],{}," 可以接收哪些类型",[15,3250,3251,3254],{},[19,3252,3253],{},"boost::asio::buffer(data)"," 的作用可以简单理解为：",[12,3256,3257],{},[15,3258,3259],{},"把一段连续内存包装成 Asio 可以使用的 buffer 描述对象。",[15,3261,3262,3263,3266],{},"它本身",[269,3264,3265],{},"不会复制数据","，主要记录的是：",[75,3268,3271],{"className":3269,"code":3270,"language":284,"meta":80},[282],"内存起始地址\n+\n内存长度\n",[19,3272,3270],{"__ignoreMap":80},[15,3274,3275],{},"所以最常见的要求是：",[12,3277,3278],{},[15,3279,3280,3283],{},[19,3281,3282],{},"data"," 最好是一段连续存储的内存。",[15,3285,3286],{},"常见可直接使用的类型包括：",[75,3288,3290],{"className":77,"code":3289,"language":79,"meta":80,"style":80},"char data[128];\n\nstd::array\u003Cchar, 128> data;\n\nstd::array\u003Cstd::uint8_t, 128> data;\n\nstd::vector\u003Cchar> data;\n\nstd::vector\u003Cstd::uint8_t> data;\n\nstd::string data;\n",[19,3291,3292,3305,3309,3325,3329,3353,3357,3369,3373,3390,3394],{"__ignoreMap":80},[84,3293,3294,3297,3300,3302],{"class":86,"line":87},[84,3295,3296],{"class":90},"char",[84,3298,3299],{"class":123}," data[",[84,3301,2995],{"class":255},[84,3303,3304],{"class":123},"];\n",[84,3306,3307],{"class":86,"line":98},[84,3308,110],{"emptyLinePlaceholder":109},[84,3310,3311,3313,3315,3317,3319,3321,3323],{"class":86,"line":106},[84,3312,522],{"class":119},[84,3314,2986],{"class":123},[84,3316,2989],{"class":90},[84,3318,2992],{"class":123},[84,3320,2995],{"class":255},[84,3322,1431],{"class":90},[84,3324,3000],{"class":123},[84,3326,3327],{"class":86,"line":113},[84,3328,110],{"emptyLinePlaceholder":109},[84,3330,3331,3333,3335,3338,3340,3342,3345,3347,3349,3351],{"class":86,"line":127},[84,3332,522],{"class":119},[84,3334,2986],{"class":123},[84,3336,3337],{"class":90},"\u003C",[84,3339,522],{"class":119},[84,3341,152],{"class":123},[84,3343,3344],{"class":90},"uint8_t",[84,3346,2992],{"class":123},[84,3348,2995],{"class":255},[84,3350,1431],{"class":90},[84,3352,3000],{"class":123},[84,3354,3355],{"class":86,"line":133},[84,3356,110],{"emptyLinePlaceholder":109},[84,3358,3359,3361,3364,3367],{"class":86,"line":140},[84,3360,522],{"class":119},[84,3362,3363],{"class":123},"::vector",[84,3365,3366],{"class":90},"\u003Cchar>",[84,3368,3000],{"class":123},[84,3370,3371],{"class":86,"line":146},[84,3372,110],{"emptyLinePlaceholder":109},[84,3374,3375,3377,3379,3381,3383,3385,3388],{"class":86,"line":161},[84,3376,522],{"class":119},[84,3378,3363],{"class":123},[84,3380,3337],{"class":90},[84,3382,522],{"class":119},[84,3384,152],{"class":123},[84,3386,3387],{"class":90},"uint8_t>",[84,3389,3000],{"class":123},[84,3391,3392],{"class":86,"line":166},[84,3393,110],{"emptyLinePlaceholder":109},[84,3395,3396,3398],{"class":86,"line":186},[84,3397,522],{"class":119},[84,3399,3400],{"class":123},"::string data;\n",[15,3402,902],{},[75,3404,3406],{"className":77,"code":3405,"language":79,"meta":80,"style":80},"std::array\u003Cstd::uint8_t, 256> data;\n\nauto buffer = boost::asio::buffer(data);\n",[19,3407,3408,3431,3435],{"__ignoreMap":80},[84,3409,3410,3412,3414,3416,3418,3420,3422,3424,3427,3429],{"class":86,"line":87},[84,3411,522],{"class":119},[84,3413,2986],{"class":123},[84,3415,3337],{"class":90},[84,3417,522],{"class":119},[84,3419,152],{"class":123},[84,3421,3344],{"class":90},[84,3423,2992],{"class":123},[84,3425,3426],{"class":255},"256",[84,3428,1431],{"class":90},[84,3430,3000],{"class":123},[84,3432,3433],{"class":86,"line":98},[84,3434,110],{"emptyLinePlaceholder":109},[84,3436,3437,3439,3442,3444,3446,3448,3450,3452,3454],{"class":86,"line":106},[84,3438,1187],{"class":90},[84,3440,3441],{"class":123}," buffer ",[84,3443,210],{"class":90},[84,3445,1195],{"class":119},[84,3447,152],{"class":123},[84,3449,155],{"class":119},[84,3451,152],{"class":123},[84,3453,34],{"class":119},[84,3455,3022],{"class":123},[15,3457,3458],{},"或者：",[75,3460,3462],{"className":77,"code":3461,"language":79,"meta":80,"style":80},"\u002F\u002F创建一个名为 data 的 std::vector，里面有 256 个 std::uint8_t 元素。\nstd::vector\u003Cstd::uint8_t> data(256);\n\nauto buffer = boost::asio::buffer(data);\n",[19,3463,3464,3469,3497,3501],{"__ignoreMap":80},[84,3465,3466],{"class":86,"line":87},[84,3467,3468],{"class":136},"\u002F\u002F创建一个名为 data 的 std::vector，里面有 256 个 std::uint8_t 元素。\n",[84,3470,3471,3473,3475,3478,3480,3482,3484,3486,3489,3491,3493,3495],{"class":86,"line":98},[84,3472,522],{"class":119},[84,3474,152],{"class":123},[84,3476,3477],{"class":119},"vector",[84,3479,3337],{"class":123},[84,3481,522],{"class":119},[84,3483,152],{"class":123},[84,3485,3344],{"class":90},[84,3487,3488],{"class":123},"> ",[84,3490,3282],{"class":119},[84,3492,177],{"class":123},[84,3494,3426],{"class":255},[84,3496,183],{"class":123},[84,3498,3499],{"class":86,"line":106},[84,3500,110],{"emptyLinePlaceholder":109},[84,3502,3503,3505,3507,3509,3511,3513,3515,3517,3519],{"class":86,"line":113},[84,3504,1187],{"class":90},[84,3506,3441],{"class":123},[84,3508,210],{"class":90},[84,3510,1195],{"class":119},[84,3512,152],{"class":123},[84,3514,155],{"class":119},[84,3516,152],{"class":123},[84,3518,34],{"class":119},[84,3520,3022],{"class":123},[15,3522,3523],{},"字符串也可以：",[75,3525,3527],{"className":77,"code":3526,"language":79,"meta":80,"style":80},"std::string message = \"hello\";\n\nauto buffer = boost::asio::buffer(message);\n",[19,3528,3529,3542,3546],{"__ignoreMap":80},[84,3530,3531,3533,3536,3538,3540],{"class":86,"line":87},[84,3532,522],{"class":119},[84,3534,3535],{"class":123},"::string message ",[84,3537,210],{"class":90},[84,3539,3187],{"class":94},[84,3541,259],{"class":123},[84,3543,3544],{"class":86,"line":98},[84,3545,110],{"emptyLinePlaceholder":109},[84,3547,3548,3550,3552,3554,3556,3558,3560,3562,3564],{"class":86,"line":106},[84,3549,1187],{"class":90},[84,3551,3441],{"class":123},[84,3553,210],{"class":90},[84,3555,1195],{"class":119},[84,3557,152],{"class":123},[84,3559,155],{"class":119},[84,3561,152],{"class":123},[84,3563,34],{"class":119},[84,3565,3566],{"class":123},"(message);\n",[15,3568,3569],{},"还可以直接指定：",[75,3571,3574],{"className":3572,"code":3573,"language":284,"meta":80},[282],"指针 + 长度\n",[19,3575,3573],{"__ignoreMap":80},[15,3577,902],{},[75,3579,3581],{"className":77,"code":3580,"language":79,"meta":80,"style":80},"std::uint8_t data[256];\n\nauto buffer =\n    boost::asio::buffer(data, 100);\n",[19,3582,3583,3597,3601,3609],{"__ignoreMap":80},[84,3584,3585,3587,3589,3591,3593,3595],{"class":86,"line":87},[84,3586,522],{"class":119},[84,3588,152],{"class":123},[84,3590,3344],{"class":90},[84,3592,3299],{"class":123},[84,3594,3426],{"class":255},[84,3596,3304],{"class":123},[84,3598,3599],{"class":86,"line":98},[84,3600,110],{"emptyLinePlaceholder":109},[84,3602,3603,3605,3607],{"class":86,"line":106},[84,3604,1187],{"class":90},[84,3606,3441],{"class":123},[84,3608,1682],{"class":90},[84,3610,3611,3613,3615,3617,3619,3621,3624,3627],{"class":86,"line":113},[84,3612,149],{"class":119},[84,3614,152],{"class":123},[84,3616,155],{"class":119},[84,3618,152],{"class":123},[84,3620,34],{"class":119},[84,3622,3623],{"class":123},"(data, ",[84,3625,3626],{"class":255},"100",[84,3628,183],{"class":123},[15,3630,3631],{},"表示只使用：",[75,3633,3636],{"className":3634,"code":3635,"language":284,"meta":80},[282],"data 开始位置后的前 100 字节\n",[19,3637,3635],{"__ignoreMap":80},[15,3639,3640],{},"也可以：",[75,3642,3644],{"className":77,"code":3643,"language":79,"meta":80,"style":80},"std::uint8_t* data = ...;\nstd::size_t size = ...;\n\nauto buffer =\n    boost::asio::buffer(data, size);\n",[19,3645,3646,3663,3678,3682,3690],{"__ignoreMap":80},[84,3647,3648,3650,3652,3655,3658,3660],{"class":86,"line":87},[84,3649,522],{"class":119},[84,3651,152],{"class":123},[84,3653,3654],{"class":90},"uint8_t*",[84,3656,3657],{"class":123}," data ",[84,3659,210],{"class":90},[84,3661,3662],{"class":123}," ...;\n",[84,3664,3665,3667,3669,3671,3674,3676],{"class":86,"line":98},[84,3666,522],{"class":119},[84,3668,152],{"class":123},[84,3670,204],{"class":90},[84,3672,3673],{"class":123}," size ",[84,3675,210],{"class":90},[84,3677,3662],{"class":123},[84,3679,3680],{"class":86,"line":106},[84,3681,110],{"emptyLinePlaceholder":109},[84,3683,3684,3686,3688],{"class":86,"line":113},[84,3685,1187],{"class":90},[84,3687,3441],{"class":123},[84,3689,1682],{"class":90},[84,3691,3692,3694,3696,3698,3700,3702],{"class":86,"line":127},[84,3693,149],{"class":119},[84,3695,152],{"class":123},[84,3697,155],{"class":119},[84,3699,152],{"class":123},[84,3701,34],{"class":119},[84,3703,3704],{"class":123},"(data, size);\n",[44,3706],{},[15,3708,3709],{},"对于串口、网络等字节流通信，通常优先使用：",[75,3711,3713],{"className":77,"code":3712,"language":79,"meta":80,"style":80},"std::uint8_t\nunsigned char\nchar\nstd::byte\n",[19,3714,3715,3724,3732,3737],{"__ignoreMap":80},[84,3716,3717,3719,3721],{"class":86,"line":87},[84,3718,522],{"class":119},[84,3720,152],{"class":123},[84,3722,3723],{"class":90},"uint8_t\n",[84,3725,3726,3729],{"class":86,"line":98},[84,3727,3728],{"class":90},"unsigned",[84,3730,3731],{"class":90}," char\n",[84,3733,3734],{"class":86,"line":106},[84,3735,3736],{"class":90},"char\n",[84,3738,3739,3741],{"class":86,"line":113},[84,3740,522],{"class":119},[84,3742,3743],{"class":123},"::byte\n",[15,3745,902],{},[75,3747,3749],{"className":77,"code":3748,"language":79,"meta":80,"style":80},"std::array\u003Cstd::uint8_t, 256> rx_buffer;\n",[19,3750,3751],{"__ignoreMap":80},[84,3752,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771],{"class":86,"line":87},[84,3754,522],{"class":119},[84,3756,2986],{"class":123},[84,3758,3337],{"class":90},[84,3760,522],{"class":119},[84,3762,152],{"class":123},[84,3764,3344],{"class":90},[84,3766,2992],{"class":123},[84,3768,3426],{"class":255},[84,3770,1431],{"class":90},[84,3772,3773],{"class":123}," rx_buffer;\n",[15,3775,3776],{},"这是很常见的接收缓冲区写法。",[44,3778],{},[15,3780,3781],{},"像下面这些容器不能简单看成一整块连续内存：",[75,3783,3785],{"className":77,"code":3784,"language":79,"meta":80,"style":80},"std::list\nstd::deque\n",[19,3786,3787,3794],{"__ignoreMap":80},[84,3788,3789,3791],{"class":86,"line":87},[84,3790,522],{"class":119},[84,3792,3793],{"class":123},"::list\n",[84,3795,3796,3798],{"class":86,"line":98},[84,3797,522],{"class":119},[84,3799,3800],{"class":123},"::deque\n",[15,3802,3803],{},"因此一般不能像：",[75,3805,3807],{"className":77,"code":3806,"language":79,"meta":80,"style":80},"std::vector\nstd::array\nstd::string\n",[19,3808,3809,3816,3823],{"__ignoreMap":80},[84,3810,3811,3813],{"class":86,"line":87},[84,3812,522],{"class":119},[84,3814,3815],{"class":123},"::vector\n",[84,3817,3818,3820],{"class":86,"line":98},[84,3819,522],{"class":119},[84,3821,3822],{"class":123},"::array\n",[84,3824,3825,3827],{"class":86,"line":106},[84,3826,522],{"class":119},[84,3828,3829],{"class":123},"::string\n",[15,3831,3832],{},"那样直接作为一整块连续 buffer 使用。",[44,3834],{},[15,3836,3837,3838,3840],{},"还要注意 ",[19,3839,402],{},"。",[15,3842,902],{},[75,3844,3846],{"className":77,"code":3845,"language":79,"meta":80,"style":80},"const std::string message = \"hello\";\n",[19,3847,3848],{"__ignoreMap":80},[84,3849,3850,3852,3854,3856,3858,3860],{"class":86,"line":87},[84,3851,402],{"class":90},[84,3853,405],{"class":119},[84,3855,3535],{"class":123},[84,3857,210],{"class":90},[84,3859,3187],{"class":94},[84,3861,259],{"class":123},[15,3863,884],{},[75,3865,3867],{"className":77,"code":3866,"language":79,"meta":80,"style":80},"boost::asio::buffer(message);\n",[19,3868,3869],{"__ignoreMap":80},[84,3870,3871,3873,3875,3877,3879,3881],{"class":86,"line":87},[84,3872,750],{"class":119},[84,3874,152],{"class":123},[84,3876,155],{"class":119},[84,3878,152],{"class":123},[84,3880,34],{"class":119},[84,3882,3566],{"class":123},[15,3884,3885],{},"得到的是只读 buffer，适合：",[75,3887,3890],{"className":3888,"code":3889,"language":284,"meta":80},[282],"发送数据\n",[19,3891,3889],{"__ignoreMap":80},[15,3893,3894],{},"但不能作为接收缓冲区，因为接收操作需要修改底层内存。",[15,3896,3897],{},"可以简单理解成：",[75,3899,3902],{"className":3900,"code":3901,"language":284,"meta":80},[282],"非 const 数据\n→ 可以生成可写 buffer\n\nconst 数据\n→ 只能生成只读 buffer\n",[19,3903,3901],{"__ignoreMap":80},[44,3905],{},[15,3907,3908],{},"最后还有一个非常重要的点：",[12,3910,3911],{},[15,3912,3913,3915,3916,3918],{},[19,3914,3253],{}," 不拥有 ",[19,3917,3282],{}," 的内存。",[15,3920,902],{},[75,3922,3924],{"className":77,"code":3923,"language":79,"meta":80,"style":80},"std::string data = \"hello\";\n\nauto buffer = boost::asio::buffer(data);\n",[19,3925,3926,3939,3943],{"__ignoreMap":80},[84,3927,3928,3930,3933,3935,3937],{"class":86,"line":87},[84,3929,522],{"class":119},[84,3931,3932],{"class":123},"::string data ",[84,3934,210],{"class":90},[84,3936,3187],{"class":94},[84,3938,259],{"class":123},[84,3940,3941],{"class":86,"line":98},[84,3942,110],{"emptyLinePlaceholder":109},[84,3944,3945,3947,3949,3951,3953,3955,3957,3959,3961],{"class":86,"line":106},[84,3946,1187],{"class":90},[84,3948,3441],{"class":123},[84,3950,210],{"class":90},[84,3952,1195],{"class":119},[84,3954,152],{"class":123},[84,3956,155],{"class":119},[84,3958,152],{"class":123},[84,3960,34],{"class":119},[84,3962,3022],{"class":123},[15,3964,3965,3966,3968,3969,3918],{},"这里 ",[19,3967,34],{}," 只是指向 ",[19,3970,3282],{},[15,3972,3973],{},"所以异步操作：",[75,3975,3977],{"className":77,"code":3976,"language":79,"meta":80,"style":80},"boost::asio::async_write(\n    socket,\n    boost::asio::buffer(data),\n    handler);\n",[19,3978,3979,3993,3998,4013],{"__ignoreMap":80},[84,3980,3981,3983,3985,3987,3989,3991],{"class":86,"line":87},[84,3982,750],{"class":119},[84,3984,152],{"class":123},[84,3986,155],{"class":119},[84,3988,152],{"class":123},[84,3990,3202],{"class":119},[84,3992,1447],{"class":123},[84,3994,3995],{"class":86,"line":98},[84,3996,3997],{"class":123},"    socket,\n",[84,3999,4000,4002,4004,4006,4008,4010],{"class":86,"line":106},[84,4001,149],{"class":119},[84,4003,152],{"class":123},[84,4005,155],{"class":119},[84,4007,152],{"class":123},[84,4009,34],{"class":119},[84,4011,4012],{"class":123},"(data),\n",[84,4014,4015],{"class":86,"line":113},[84,4016,4017],{"class":123},"    handler);\n",[15,4019,4020],{},"完成之前，必须保证：",[75,4022,4025],{"className":4023,"code":4024,"language":284,"meta":80},[282],"data 仍然存在\n\n并且底层内存没有失效\n",[19,4026,4024],{"__ignoreMap":80},[15,4028,4029],{},"因此可以把：",[75,4031,4032],{"className":77,"code":2860,"language":79,"meta":80,"style":80},[19,4033,4034],{"__ignoreMap":80},[84,4035,4036,4038,4040,4042,4044,4046],{"class":86,"line":87},[84,4037,750],{"class":119},[84,4039,152],{"class":123},[84,4041,155],{"class":119},[84,4043,152],{"class":123},[84,4045,34],{"class":119},[84,4047,2877],{"class":123},[15,4049,4050],{},"简单记成：",[12,4052,4053],{},[15,4054,4055],{},"把一段连续内存包装成“地址 + 长度”的 Asio buffer，并不会复制或拥有这段数据。",[44,4057],{},[47,4059,4061,4062,4064],{"id":4060},"示例-5类里封装-io_context-工作线程","示例 5：类里封装 ",[19,4063,21],{}," 工作线程",[58,4066,60],{"id":4067},"程序目标-4",[15,4069,4070,4071,4073,4074,4077],{},"工程里经常希望 Asio 在单独线程运行。",[40,4072],{},"\n本例写一个最小的 ",[19,4075,4076],{},"IoThread"," 类：",[766,4079,4080,4085,4093,4099],{},[769,4081,4082,4083,777],{},"构造时创建 ",[19,4084,31],{},[769,4086,4087,4090,4091,777],{},[19,4088,4089],{},"start()"," 开线程执行 ",[19,4092,69],{},[769,4094,4095,4098],{},[19,4096,4097],{},"stop()"," 停止线程；",[769,4100,4101,4102,4104],{},"用 ",[19,4103,28],{}," 投递任务验证效果。",[58,4106,73],{"id":4107},"完整代码-4",[75,4109,4111],{"className":77,"code":4110,"language":79,"meta":80,"style":80},"#include \u003Cboost\u002Fasio.hpp>\n#include \u003Cfunctional>\n#include \u003Cprint>\n#include \u003Cmemory>\n#include \u003Cstring>\n#include \u003Cthread>\n\nclass IoThread\n{\npublic:\n    IoThread()\n        : guard_(boost::asio::make_work_guard(io_))\n    {\n    }\n\n    ~IoThread()\n    {\n        stop();\n    }\n\n    void start()\n    {\n        thread_ = std::thread(std::bind(&IoThread::run, this));\n    }\n\n    void stop()\n    {\n        if (!stopped_)\n        {\n            stopped_ = true;\n            guard_.reset();\n            io_.stop();\n\n            if (thread_.joinable())\n            {\n                thread_.join();\n            }\n        }\n    }\n\n    boost::asio::io_context& io()\n    {\n        return io_;\n    }\n\nprivate:\n    void run()\n    {\n        std::println(\"IoThread：io.run() 开始\");\n        \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n        io_.run();\n        std::println(\"IoThread：io.run() 返回\");\n    }\n\nprivate:\n    \u002F\u002F io_context 是 Asio 的事件循环对象，异步任务需要靠它调度。\n    boost::asio::io_context io_;\n    boost::asio::executor_work_guard\u003Cboost::asio::io_context::executor_type> guard_;\n    std::thread thread_;\n    bool stopped_ = false;\n};\n\nvoid print_task(const std::string& msg)\n{\n    std::println(\"执行任务：{}\", msg);\n}\n\nint main()\n{\n    \u002F\u002F 程序从 main 函数开始执行，下面的语句会按顺序运行。\n    IoThread io_thread;\n    io_thread.start();\n\n    \u002F\u002F post 只是把任务放进队列，真正执行要等 io.run()。\n    boost::asio::post(io_thread.io(), std::bind(print_task, std::string(\"A\")));\n    boost::asio::post(io_thread.io(), std::bind(print_task, std::string(\"B\")));\n\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n\n    std::println(\"main：准备停止 IoThread\");\n    io_thread.stop();\n\n    std::println(\"main：结束\");\n\n    return 0;\n}\n",[19,4112,4113,4119,4125,4131,4138,4144,4150,4154,4162,4166,4171,4178,4201,4206,4211,4215,4222,4226,4233,4237,4241,4251,4255,4291,4295,4299,4308,4312,4325,4330,4342,4351,4360,4364,4378,4383,4392,4397,4402,4406,4410,4428,4432,4440,4444,4448,4453,4462,4466,4481,4486,4495,4510,4514,4518,4522,4526,4537,4566,4573,4589,4595,4600,4624,4629,4644,4649,4654,4663,4668,4673,4679,4690,4695,4700,4742,4781,4786,4820,4825,4841,4850,4855,4871,4876,4885],{"__ignoreMap":80},[84,4114,4115,4117],{"class":86,"line":87},[84,4116,91],{"class":90},[84,4118,95],{"class":94},[84,4120,4121,4123],{"class":86,"line":98},[84,4122,91],{"class":90},[84,4124,372],{"class":94},[84,4126,4127,4129],{"class":86,"line":106},[84,4128,91],{"class":90},[84,4130,103],{"class":94},[84,4132,4133,4135],{"class":86,"line":113},[84,4134,91],{"class":90},[84,4136,4137],{"class":94}," \u003Cmemory>\n",[84,4139,4140,4142],{"class":86,"line":127},[84,4141,91],{"class":90},[84,4143,385],{"class":94},[84,4145,4146,4148],{"class":86,"line":133},[84,4147,91],{"class":90},[84,4149,1363],{"class":94},[84,4151,4152],{"class":86,"line":140},[84,4153,110],{"emptyLinePlaceholder":109},[84,4155,4156,4159],{"class":86,"line":146},[84,4157,4158],{"class":90},"class",[84,4160,4161],{"class":119}," IoThread\n",[84,4163,4164],{"class":86,"line":161},[84,4165,130],{"class":123},[84,4167,4168],{"class":86,"line":166},[84,4169,4170],{"class":90},"public:\n",[84,4172,4173,4176],{"class":86,"line":186},[84,4174,4175],{"class":119},"    IoThread",[84,4177,124],{"class":123},[84,4179,4180,4183,4186,4188,4190,4192,4194,4196,4198],{"class":86,"line":191},[84,4181,4182],{"class":123},"        : ",[84,4184,4185],{"class":119},"guard_",[84,4187,177],{"class":123},[84,4189,750],{"class":119},[84,4191,152],{"class":123},[84,4193,155],{"class":119},[84,4195,152],{"class":123},[84,4197,1204],{"class":119},[84,4199,4200],{"class":123},"(io_))\n",[84,4202,4203],{"class":86,"line":197},[84,4204,4205],{"class":123},"    {\n",[84,4207,4208],{"class":86,"line":222},[84,4209,4210],{"class":123},"    }\n",[84,4212,4213],{"class":86,"line":227},[84,4214,110],{"emptyLinePlaceholder":109},[84,4216,4217,4220],{"class":86,"line":244},[84,4218,4219],{"class":119},"    ~IoThread",[84,4221,124],{"class":123},[84,4223,4224],{"class":86,"line":249},[84,4225,4205],{"class":123},[84,4227,4228,4231],{"class":86,"line":262},[84,4229,4230],{"class":119},"        stop",[84,4232,219],{"class":123},[84,4234,4235],{"class":86,"line":505},[84,4236,4210],{"class":123},[84,4238,4239],{"class":86,"line":547},[84,4240,110],{"emptyLinePlaceholder":109},[84,4242,4243,4246,4249],{"class":86,"line":552},[84,4244,4245],{"class":90},"    void",[84,4247,4248],{"class":119}," start",[84,4250,124],{"class":123},[84,4252,4253],{"class":86,"line":568},[84,4254,4205],{"class":123},[84,4256,4257,4260,4262,4264,4266,4268,4270,4272,4274,4276,4278,4280,4282,4285,4288],{"class":86,"line":604},[84,4258,4259],{"class":123},"        thread_ ",[84,4261,210],{"class":90},[84,4263,405],{"class":119},[84,4265,152],{"class":123},[84,4267,1960],{"class":119},[84,4269,177],{"class":123},[84,4271,522],{"class":119},[84,4273,152],{"class":123},[84,4275,527],{"class":119},[84,4277,177],{"class":123},[84,4279,413],{"class":90},[84,4281,4076],{"class":119},[84,4283,4284],{"class":123},"::run, ",[84,4286,4287],{"class":255},"this",[84,4289,4290],{"class":123},"));\n",[84,4292,4293],{"class":86,"line":609},[84,4294,4210],{"class":123},[84,4296,4297],{"class":86,"line":624},[84,4298,110],{"emptyLinePlaceholder":109},[84,4300,4301,4303,4306],{"class":86,"line":629},[84,4302,4245],{"class":90},[84,4304,4305],{"class":119}," stop",[84,4307,124],{"class":123},[84,4309,4310],{"class":86,"line":634},[84,4311,4205],{"class":123},[84,4313,4314,4317,4319,4322],{"class":86,"line":653},[84,4315,4316],{"class":90},"        if",[84,4318,1293],{"class":123},[84,4320,4321],{"class":90},"!",[84,4323,4324],{"class":123},"stopped_)\n",[84,4326,4327],{"class":86,"line":658},[84,4328,4329],{"class":123},"        {\n",[84,4331,4332,4335,4337,4340],{"class":86,"line":674},[84,4333,4334],{"class":123},"            stopped_ ",[84,4336,210],{"class":90},[84,4338,4339],{"class":255}," true",[84,4341,259],{"class":123},[84,4343,4344,4347,4349],{"class":86,"line":679},[84,4345,4346],{"class":123},"            guard_.",[84,4348,1631],{"class":119},[84,4350,219],{"class":123},[84,4352,4353,4356,4358],{"class":86,"line":688},[84,4354,4355],{"class":123},"            io_.",[84,4357,2552],{"class":119},[84,4359,219],{"class":123},[84,4361,4362],{"class":86,"line":1636},[84,4363,110],{"emptyLinePlaceholder":109},[84,4365,4366,4369,4372,4375],{"class":86,"line":1641},[84,4367,4368],{"class":90},"            if",[84,4370,4371],{"class":123}," (thread_.",[84,4373,4374],{"class":119},"joinable",[84,4376,4377],{"class":123},"())\n",[84,4379,4380],{"class":86,"line":1646},[84,4381,4382],{"class":123},"            {\n",[84,4384,4385,4388,4390],{"class":86,"line":1655},[84,4386,4387],{"class":123},"                thread_.",[84,4389,1838],{"class":119},[84,4391,219],{"class":123},[84,4393,4394],{"class":86,"line":1660},[84,4395,4396],{"class":123},"            }\n",[84,4398,4399],{"class":86,"line":1671},[84,4400,4401],{"class":123},"        }\n",[84,4403,4404],{"class":86,"line":1676},[84,4405,4210],{"class":123},[84,4407,4408],{"class":86,"line":1685},[84,4409,110],{"emptyLinePlaceholder":109},[84,4411,4412,4414,4416,4418,4420,4422,4424,4426],{"class":86,"line":1700},[84,4413,149],{"class":119},[84,4415,152],{"class":123},[84,4417,155],{"class":119},[84,4419,152],{"class":123},[84,4421,21],{"class":119},[84,4423,413],{"class":90},[84,4425,1465],{"class":119},[84,4427,124],{"class":123},[84,4429,4430],{"class":86,"line":1705},[84,4431,4205],{"class":123},[84,4433,4434,4437],{"class":86,"line":1718},[84,4435,4436],{"class":90},"        return",[84,4438,4439],{"class":123}," io_;\n",[84,4441,4442],{"class":86,"line":1730},[84,4443,4210],{"class":123},[84,4445,4446],{"class":86,"line":1736},[84,4447,110],{"emptyLinePlaceholder":109},[84,4449,4450],{"class":86,"line":1744},[84,4451,4452],{"class":90},"private:\n",[84,4454,4455,4457,4460],{"class":86,"line":1752},[84,4456,4245],{"class":90},[84,4458,4459],{"class":119}," run",[84,4461,124],{"class":123},[84,4463,4464],{"class":86,"line":1757},[84,4465,4205],{"class":123},[84,4467,4468,4470,4472,4474,4476,4479],{"class":86,"line":1773},[84,4469,1721],{"class":119},[84,4471,152],{"class":123},[84,4473,174],{"class":119},[84,4475,177],{"class":123},[84,4477,4478],{"class":94},"\"IoThread：io.run() 开始\"",[84,4480,183],{"class":123},[84,4482,4483],{"class":86,"line":1778},[84,4484,4485],{"class":136},"        \u002F\u002F 启动事件循环，前面注册的异步任务会在这里被调度执行。\n",[84,4487,4488,4491,4493],{"class":86,"line":1797},[84,4489,4490],{"class":123},"        io_.",[84,4492,216],{"class":119},[84,4494,219],{"class":123},[84,4496,4497,4499,4501,4503,4505,4508],{"class":86,"line":1802},[84,4498,1721],{"class":119},[84,4500,152],{"class":123},[84,4502,174],{"class":119},[84,4504,177],{"class":123},[84,4506,4507],{"class":94},"\"IoThread：io.run() 返回\"",[84,4509,183],{"class":123},[84,4511,4512],{"class":86,"line":1813},[84,4513,4210],{"class":123},[84,4515,4516],{"class":86,"line":1821},[84,4517,110],{"emptyLinePlaceholder":109},[84,4519,4520],{"class":86,"line":1827},[84,4521,4452],{"class":90},[84,4523,4524],{"class":86,"line":1832},[84,4525,143],{"class":136},[84,4527,4528,4530,4532,4534],{"class":86,"line":1843},[84,4529,149],{"class":119},[84,4531,152],{"class":123},[84,4533,155],{"class":119},[84,4535,4536],{"class":123},"::io_context io_;\n",[84,4538,4539,4541,4543,4545,4547,4549,4551,4553,4555,4557,4559,4561,4563],{"class":86,"line":1848},[84,4540,149],{"class":119},[84,4542,152],{"class":123},[84,4544,155],{"class":119},[84,4546,1409],{"class":123},[84,4548,3337],{"class":90},[84,4550,750],{"class":119},[84,4552,152],{"class":123},[84,4554,155],{"class":119},[84,4556,152],{"class":123},[84,4558,21],{"class":119},[84,4560,1428],{"class":123},[84,4562,1431],{"class":90},[84,4564,4565],{"class":123}," guard_;\n",[84,4567,4568,4570],{"class":86,"line":1857},[84,4569,169],{"class":119},[84,4571,4572],{"class":123},"::thread thread_;\n",[84,4574,4576,4579,4582,4584,4587],{"class":86,"line":4575},60,[84,4577,4578],{"class":90},"    bool",[84,4580,4581],{"class":123}," stopped_ ",[84,4583,210],{"class":90},[84,4585,4586],{"class":255}," false",[84,4588,259],{"class":123},[84,4590,4592],{"class":86,"line":4591},61,[84,4593,4594],{"class":123},"};\n",[84,4596,4598],{"class":86,"line":4597},62,[84,4599,110],{"emptyLinePlaceholder":109},[84,4601,4603,4605,4608,4610,4612,4614,4616,4618,4620,4622],{"class":86,"line":4602},63,[84,4604,394],{"class":90},[84,4606,4607],{"class":119}," print_task",[84,4609,177],{"class":123},[84,4611,402],{"class":90},[84,4613,405],{"class":119},[84,4615,152],{"class":123},[84,4617,410],{"class":119},[84,4619,413],{"class":90},[84,4621,417],{"class":416},[84,4623,420],{"class":123},[84,4625,4627],{"class":86,"line":4626},64,[84,4628,130],{"class":123},[84,4630,4632,4634,4636,4638,4640,4642],{"class":86,"line":4631},65,[84,4633,169],{"class":119},[84,4635,152],{"class":123},[84,4637,174],{"class":119},[84,4639,177],{"class":123},[84,4641,437],{"class":94},[84,4643,440],{"class":123},[84,4645,4647],{"class":86,"line":4646},66,[84,4648,265],{"class":123},[84,4650,4652],{"class":86,"line":4651},67,[84,4653,110],{"emptyLinePlaceholder":109},[84,4655,4657,4659,4661],{"class":86,"line":4656},68,[84,4658,116],{"class":90},[84,4660,120],{"class":119},[84,4662,124],{"class":123},[84,4664,4666],{"class":86,"line":4665},69,[84,4667,130],{"class":123},[84,4669,4671],{"class":86,"line":4670},70,[84,4672,137],{"class":136},[84,4674,4676],{"class":86,"line":4675},71,[84,4677,4678],{"class":123},"    IoThread io_thread;\n",[84,4680,4682,4685,4688],{"class":86,"line":4681},72,[84,4683,4684],{"class":123},"    io_thread.",[84,4686,4687],{"class":119},"start",[84,4689,219],{"class":123},[84,4691,4693],{"class":86,"line":4692},73,[84,4694,110],{"emptyLinePlaceholder":109},[84,4696,4698],{"class":86,"line":4697},74,[84,4699,502],{"class":136},[84,4701,4703,4705,4707,4709,4711,4713,4716,4718,4721,4723,4725,4727,4730,4732,4734,4736,4738,4740],{"class":86,"line":4702},75,[84,4704,149],{"class":119},[84,4706,152],{"class":123},[84,4708,155],{"class":119},[84,4710,152],{"class":123},[84,4712,516],{"class":119},[84,4714,4715],{"class":123},"(io_thread.",[84,4717,773],{"class":119},[84,4719,4720],{"class":123},"(), ",[84,4722,522],{"class":119},[84,4724,152],{"class":123},[84,4726,527],{"class":119},[84,4728,4729],{"class":123},"(print_task, ",[84,4731,522],{"class":119},[84,4733,152],{"class":123},[84,4735,410],{"class":119},[84,4737,177],{"class":123},[84,4739,541],{"class":94},[84,4741,544],{"class":123},[84,4743,4745,4747,4749,4751,4753,4755,4757,4759,4761,4763,4765,4767,4769,4771,4773,4775,4777,4779],{"class":86,"line":4744},76,[84,4746,149],{"class":119},[84,4748,152],{"class":123},[84,4750,155],{"class":119},[84,4752,152],{"class":123},[84,4754,516],{"class":119},[84,4756,4715],{"class":123},[84,4758,773],{"class":119},[84,4760,4720],{"class":123},[84,4762,522],{"class":119},[84,4764,152],{"class":123},[84,4766,527],{"class":119},[84,4768,4729],{"class":123},[84,4770,522],{"class":119},[84,4772,152],{"class":123},[84,4774,410],{"class":119},[84,4776,177],{"class":123},[84,4778,599],{"class":94},[84,4780,544],{"class":123},[84,4782,4784],{"class":86,"line":4783},77,[84,4785,110],{"emptyLinePlaceholder":109},[84,4787,4789,4791,4793,4795,4797,4799,4801,4803,4805,4808,4810,4813,4815,4818],{"class":86,"line":4788},78,[84,4790,169],{"class":119},[84,4792,152],{"class":123},[84,4794,1512],{"class":119},[84,4796,152],{"class":123},[84,4798,1517],{"class":119},[84,4800,177],{"class":123},[84,4802,522],{"class":119},[84,4804,152],{"class":123},[84,4806,4807],{"class":119},"chrono",[84,4809,152],{"class":123},[84,4811,4812],{"class":119},"seconds",[84,4814,177],{"class":123},[84,4816,4817],{"class":255},"1",[84,4819,4290],{"class":123},[84,4821,4823],{"class":86,"line":4822},79,[84,4824,110],{"emptyLinePlaceholder":109},[84,4826,4828,4830,4832,4834,4836,4839],{"class":86,"line":4827},80,[84,4829,169],{"class":119},[84,4831,152],{"class":123},[84,4833,174],{"class":119},[84,4835,177],{"class":123},[84,4837,4838],{"class":94},"\"main：准备停止 IoThread\"",[84,4840,183],{"class":123},[84,4842,4844,4846,4848],{"class":86,"line":4843},81,[84,4845,4684],{"class":123},[84,4847,2552],{"class":119},[84,4849,219],{"class":123},[84,4851,4853],{"class":86,"line":4852},82,[84,4854,110],{"emptyLinePlaceholder":109},[84,4856,4858,4860,4862,4864,4866,4869],{"class":86,"line":4857},83,[84,4859,169],{"class":119},[84,4861,152],{"class":123},[84,4863,174],{"class":119},[84,4865,177],{"class":123},[84,4867,4868],{"class":94},"\"main：结束\"",[84,4870,183],{"class":123},[84,4872,4874],{"class":86,"line":4873},84,[84,4875,110],{"emptyLinePlaceholder":109},[84,4877,4879,4881,4883],{"class":86,"line":4878},85,[84,4880,252],{"class":90},[84,4882,256],{"class":255},[84,4884,259],{"class":123},[84,4886,4888],{"class":86,"line":4887},86,[84,4889,265],{"class":123},[15,4891,4892,272],{},[269,4893,271],{},[58,4895,275],{"id":4896},"运行输出与时间顺序-2",[15,4898,4899],{},"程序启动后，工作线程开始运行：",[75,4901,4904],{"className":4902,"code":4903,"language":284,"meta":80},[282],"IoThread：io.run() 开始\n执行任务：A\n执行任务：B\n",[19,4905,4903],{"__ignoreMap":80},[15,4907,4908],{},"约 1 秒后主线程停止它：",[75,4910,4913],{"className":4911,"code":4912,"language":284,"meta":80},[282],"main：准备停止 IoThread\nIoThread：io.run() 返回\nmain：结束\n",[19,4914,4912],{"__ignoreMap":80},[15,4916,4917],{},"完整输出类似：",[75,4919,4922],{"className":4920,"code":4921,"language":284,"meta":80},[282],"IoThread：io.run() 开始\n执行任务：A\n执行任务：B\nmain：准备停止 IoThread\nIoThread：io.run() 返回\nmain：结束\n",[19,4923,4921],{"__ignoreMap":80},[58,4925,289],{"id":4926},"本示例需要注意的点-3",[15,4928,4929],{},"这个类就是以后封装串口、TCP、UDP 通信线程的雏形。",[15,4931,4932],{},"但注意：",[75,4934,4936],{"className":77,"code":4935,"language":79,"meta":80,"style":80},"io_.stop();\n",[19,4937,4938],{"__ignoreMap":80},[84,4939,4940,4943,4945],{"class":86,"line":87},[84,4941,4942],{"class":123},"io_.",[84,4944,2552],{"class":119},[84,4946,219],{"class":123},[15,4948,4949,4950,4952],{},"会让 ",[19,4951,21],{}," 尽快停止，未完成的异步任务可能不会正常完成。",[15,4954,4955],{},"工程里更细致的做法是：",[75,4957,4960],{"className":4958,"code":4959,"language":284,"meta":80},[282],"先 cancel socket \u002F timer \u002F serial_port\n再 reset work_guard\n最后等待 run() 返回\n",[19,4961,4959],{"__ignoreMap":80},[44,4963],{},[47,4965,4966],{"id":4966},"本节总结",[766,4968,4969,4974,4981,4989,4994,4999],{},[769,4970,1309,4971,4973],{},[19,4972,69],{}," 立刻返回。",[769,4975,4976,4978,4979,351],{},[19,4977,28],{}," 可以把普通函数投递给 ",[19,4980,21],{},[769,4982,4983,4985,4986,4988],{},[19,4984,31],{}," 可以防止 ",[19,4987,69],{}," 因为没任务而退出。",[769,4990,4991,4993],{},[19,4992,37],{}," 可以绑定普通函数，也可以绑定成员函数。",[769,4995,4996,4998],{},[19,4997,3145],{}," 通常只是内存视图，不负责延长数据生命周期。",[769,5000,5001],{},"异步工程里最重要的是对象生命周期和 buffer 生命周期。",[5003,5004,5005],"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":80,"searchDepth":98,"depth":98,"links":5007},[5008,5017,5028,5050,5059,5066],{"id":49,"depth":98,"text":5009,"children":5010},"示例 1：io_context 没有任务时，run() 立刻返回",[5011,5012,5013,5014,5015],{"id":60,"depth":106,"text":60},{"id":73,"depth":106,"text":73},{"id":275,"depth":106,"text":275},{"id":289,"depth":106,"text":289},{"id":306,"depth":106,"text":5016},"io.run() 返回值",{"id":328,"depth":98,"text":5018,"children":5019},"示例 2：普通 main() 里用 post() 投递任务",[5020,5021,5022,5023,5024,5026],{"id":339,"depth":106,"text":60},{"id":354,"depth":106,"text":73},{"id":697,"depth":106,"text":275},{"id":709,"depth":106,"text":289},{"id":737,"depth":106,"text":5025},"post() 函数说明",{"id":789,"depth":106,"text":5027},"std::bind 说明",{"id":844,"depth":98,"text":5029,"children":5030},"示例 3：work_guard 让 io.run() 等待未来任务",[5031,5032,5034,5036,5037,5038,5039,5041,5042,5044,5046,5047,5049],{"id":854,"depth":106,"text":60},{"id":1012,"depth":106,"text":5033},"如果没有 work_guard",{"id":1171,"depth":106,"text":5035},"work_guard 到底做了什么",{"id":1317,"depth":106,"text":73},{"id":1876,"depth":106,"text":1876},{"id":2055,"depth":106,"text":2056},{"id":2182,"depth":106,"text":5040},"guard.reset() 到底做什么",{"id":2314,"depth":106,"text":2315},{"id":2404,"depth":106,"text":5043},"如果一直不 reset() 会怎样",{"id":2503,"depth":106,"text":5045},"reset() 和 io.stop() 不一样",{"id":2628,"depth":106,"text":2629},{"id":2707,"depth":106,"text":5048},"make_work_guard() 和 reset() 怎么记",{"id":2796,"depth":106,"text":2796},{"id":2847,"depth":98,"text":5051,"children":5052},"示例 4：buffer 的基本使用",[5053,5054,5055,5056,5057],{"id":2854,"depth":106,"text":60},{"id":2883,"depth":106,"text":73},{"id":3131,"depth":106,"text":3131},{"id":3140,"depth":106,"text":289},{"id":3245,"depth":106,"text":5058},"boost::asio::buffer() 可以接收哪些类型",{"id":4060,"depth":98,"text":5060,"children":5061},"示例 5：类里封装 io_context 工作线程",[5062,5063,5064,5065],{"id":4067,"depth":106,"text":60},{"id":4107,"depth":106,"text":73},{"id":4896,"depth":106,"text":275},{"id":4926,"depth":106,"text":289},{"id":4966,"depth":98,"text":4966},"2100-0100-0200","2023-10-05","2023-10-05-cplusplus-jiao-xue","\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue","Cplusplus教学","md",false,{},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0200-boost-asio-ji-chu",{"title":5,"description":80},"wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0200-Boost.Asio基础","ku4kDGcKZ15Skfx_dLQsqL3k4arDI-VJ5TWuS47GD7k",[5080,5087,5093,5099,5105,5111,5117,5123,5129,5135,5141,5147,5153,5159,5165,5171,5177,5183,5189,5195,5201,5207,5213,5219,5225,5231,5237,5243,5249,5255,5261,5267,5273,5279,5285,5291,5297,5303,5309,5315,5320,5326,5331,5337,5343,5349,5355,5361,5367,5373,5379,5385,5390,5396,5402,5408,5414,5420,5426,5432,5438,5444,5450,5456,5462,5468,5474,5480,5486,5492,5498,5504,5510,5516,5518,5524,5530,5536,5542,5548,5554,5560,5566,5572,5578,5584,5590,5596,5602,5608,5614,5620],{"path":5081,"stem":5082,"title":5083,"authors":5084,"date":5068,"chapterOrder":5085,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0100-c-kai-fa-huan-jing-da-jian-yu-ce-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F0100-C++开发环境搭建与测试","C++开发环境搭建与测试",[7],"0100",0,{"path":5088,"stem":5089,"title":5090,"authors":5091,"date":5068,"chapterOrder":5092,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0200-c-ji-chu-chu-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F0200-C++基础初识","C++基础初识",[7],"0200",{"path":5094,"stem":5095,"title":5096,"authors":5097,"date":5068,"chapterOrder":5098,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0300-shu-ju-lei-xing-yu-shu-ju-cun-fang","wiki\u002F2023-10-05-Cplusplus教学\u002F0300-数据类型与数据存放","数据类型与数据存放",[7],"0300",{"path":5100,"stem":5101,"title":5102,"authors":5103,"date":5068,"chapterOrder":5104,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0400-shu-ru-shu-chu","wiki\u002F2023-10-05-Cplusplus教学\u002F0400-输入输出","输入输出",[7],"0400",{"path":5106,"stem":5107,"title":5108,"authors":5109,"date":5068,"chapterOrder":5110,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0500-yun-suan-fu","wiki\u002F2023-10-05-Cplusplus教学\u002F0500-运算符","运算符",[7],"0500",{"path":5112,"stem":5113,"title":5114,"authors":5115,"date":5068,"chapterOrder":5116,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0600-cheng-xu-liu-cheng-jie-gou","wiki\u002F2023-10-05-Cplusplus教学\u002F0600-程序流程结构","程序流程结构",[7],"0600",{"path":5118,"stem":5119,"title":5120,"authors":5121,"date":5068,"chapterOrder":5122,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0700-shu-zu","wiki\u002F2023-10-05-Cplusplus教学\u002F0700-数组","数组",[7],"0700",{"path":5124,"stem":5125,"title":5126,"authors":5127,"date":5068,"chapterOrder":5128,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0800-han-shu-yu-tou-wen-jian","wiki\u002F2023-10-05-Cplusplus教学\u002F0800-函数与头文件","函数与头文件",[7],"0800",{"path":5130,"stem":5131,"title":5132,"authors":5133,"date":5068,"chapterOrder":5134,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0900-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F0900-指针","指针",[7],"0900",{"path":5136,"stem":5137,"title":5138,"authors":5139,"date":5068,"chapterOrder":5140,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1000-jie-gou-ti-yu-gong-yong-ti","wiki\u002F2023-10-05-Cplusplus教学\u002F1000-结构体与共用体","结构体与共用体",[7],"1000",{"path":5142,"stem":5143,"title":5144,"authors":5145,"date":5068,"chapterOrder":5146,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1100-nei-cun-fen-qu-yu-sheng-ming-zhou-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1100-内存分区与生命周期","内存分区与生命周期",[7],"1100",{"path":5148,"stem":5149,"title":5150,"authors":5151,"date":5068,"chapterOrder":5152,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1200-yin-yong","wiki\u002F2023-10-05-Cplusplus教学\u002F1200-引用","引用",[7],"1200",{"path":5154,"stem":5155,"title":5156,"authors":5157,"date":5068,"chapterOrder":5158,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1300-han-shu-ti-gao","wiki\u002F2023-10-05-Cplusplus教学\u002F1300-函数提高","函数提高",[7],"1300",{"path":5160,"stem":5161,"title":5162,"authors":5163,"date":5068,"chapterOrder":5164,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1350-ming-ming-kong-jian","wiki\u002F2023-10-05-Cplusplus教学\u002F1350-命名空间","命名空间",[7],"1350",{"path":5166,"stem":5167,"title":5168,"authors":5169,"date":5068,"chapterOrder":5170,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0100-feng-zhuang","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0100-封装","封装",[7],"1400-0100",{"path":5172,"stem":5173,"title":5174,"authors":5175,"date":5068,"chapterOrder":5176,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0200-dui-xiang-chu-shi-hua-he-qing-li","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0200-对象初始化和清理","对象初始化和清理",[7],"1400-0200",{"path":5178,"stem":5179,"title":5180,"authors":5181,"date":5068,"chapterOrder":5182,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0300-dui-xiang-mo-xing-yu-this-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0300-对象模型与this指针","对象模型与this指针",[7],"1400-0300",{"path":5184,"stem":5185,"title":5186,"authors":5187,"date":5068,"chapterOrder":5188,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0400-you-yuan-yu-yun-suan-fu-zhong-zai","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0400-友元与运算符重载","友元与运算符重载",[7],"1400-0400",{"path":5190,"stem":5191,"title":5192,"authors":5193,"date":5068,"chapterOrder":5194,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0500-ji-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0500-继承","继承",[7],"1400-0500",{"path":5196,"stem":5197,"title":5198,"authors":5199,"date":5068,"chapterOrder":5200,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0600-duo-tai","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0600-多态","多态",[7],"1400-0600",{"path":5202,"stem":5203,"title":5204,"authors":5205,"date":5068,"chapterOrder":5206,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-lei-he-dui-xiang","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-类和对象","类和对象",[7],"1400",{"path":5208,"stem":5209,"title":5210,"authors":5211,"date":5068,"chapterOrder":5212,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1450-han-shu-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F1450-函数指针","函数指针",[7],"1450",{"path":5214,"stem":5215,"title":5216,"authors":5217,"date":5068,"chapterOrder":5218,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1500-wen-jian-cao-zuo","wiki\u002F2023-10-05-Cplusplus教学\u002F1500-文件操作","文件操作",[7],"1500",{"path":5220,"stem":5221,"title":5222,"authors":5223,"date":5068,"chapterOrder":5224,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1600-yi-chang-chu-li-yu-cuo-wu-ma","wiki\u002F2023-10-05-Cplusplus教学\u002F1600-异常处理与错误码","异常处理",[7],"1600",{"path":5226,"stem":5227,"title":5228,"authors":5229,"date":5068,"chapterOrder":5230,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1700-mu-ban","wiki\u002F2023-10-05-Cplusplus教学\u002F1700-模板","模板",[7],"1700",{"path":5232,"stem":5233,"title":5234,"authors":5235,"date":5068,"chapterOrder":5236,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0100-stl-chu-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0100-STL初识","STL初识",[7],"1800-0100",{"path":5238,"stem":5239,"title":5240,"authors":5241,"date":5068,"chapterOrder":5242,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0200-std-array","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0200-std-array","std::array",[7],"1800-0200",{"path":5244,"stem":5245,"title":5246,"authors":5247,"date":5068,"chapterOrder":5248,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0300-string-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0300-string容器","string容器",[7],"1800-0300",{"path":5250,"stem":5251,"title":5252,"authors":5253,"date":5068,"chapterOrder":5254,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0400-vector-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0400-vector容器","vector 容器",[7],"1800-0400",{"path":5256,"stem":5257,"title":5258,"authors":5259,"date":5068,"chapterOrder":5260,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0500-deque-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0500-deque容器","deque 容器",[7],"1800-0500",{"path":5262,"stem":5263,"title":5264,"authors":5265,"date":5068,"chapterOrder":5266,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0600-stack-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0600-stack容器","stack 容器",[7],"1800-0600",{"path":5268,"stem":5269,"title":5270,"authors":5271,"date":5068,"chapterOrder":5272,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0700-queue-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0700-queue容器","queue 容器",[7],"1800-0700",{"path":5274,"stem":5275,"title":5276,"authors":5277,"date":5068,"chapterOrder":5278,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0800-list-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0800-list容器","list 容器",[7],"1800-0800",{"path":5280,"stem":5281,"title":5282,"authors":5283,"date":5068,"chapterOrder":5284,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0900-set-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0900-set容器","set \u002F multiset 容器",[7],"1800-0900",{"path":5286,"stem":5287,"title":5288,"authors":5289,"date":5068,"chapterOrder":5290,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1000-map-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1000-map容器","map \u002F multimap 容器",[7],"1800-1000",{"path":5292,"stem":5293,"title":5294,"authors":5295,"date":5068,"chapterOrder":5296,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1100-han-shu-dui-xiang-yu-wei-ci","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1100-函数对象与谓词","函数对象与谓词",[7],"1800-1100",{"path":5298,"stem":5299,"title":5300,"authors":5301,"date":5068,"chapterOrder":5302,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1200-chang-yong-suan-fa","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1200-常用算法","常用算法",[7],"1800-1200",{"path":5304,"stem":5305,"title":5306,"authors":5307,"date":5068,"chapterOrder":5308,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-stl-ti-gao-bian-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-STL提高编程","STL提高编程",[7],"1800",{"path":5310,"stem":5311,"title":5312,"authors":5313,"date":5068,"chapterOrder":5314,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1900-c-lei-xing-zhuan-huan","wiki\u002F2023-10-05-Cplusplus教学\u002F1900-C++类型转换","C++类型转换",[7],"1900",{"path":5316,"stem":5317,"title":1187,"authors":5318,"date":5068,"chapterOrder":5319,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0100-auto","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0100-auto",[7],"2000-0100",{"path":5321,"stem":5322,"title":5323,"authors":5324,"date":5068,"chapterOrder":5325,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0200-nullptr","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0200-nullptr","nullptr",[7],"2000-0200",{"path":5327,"stem":5328,"title":1372,"authors":5329,"date":5068,"chapterOrder":5330,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0300-using","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0300-using",[7],"2000-0300",{"path":5332,"stem":5333,"title":5334,"authors":5335,"date":5068,"chapterOrder":5336,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0400-enum-class","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0400-enum-class","enum class",[7],"2000-0400",{"path":5338,"stem":5339,"title":5340,"authors":5341,"date":5068,"chapterOrder":5342,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0500-fan-wei-for-xun-huan","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0500-范围for循环","范围 for 循环",[7],"2000-0500",{"path":5344,"stem":5345,"title":5346,"authors":5347,"date":5068,"chapterOrder":5348,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0600-jie-gou-hua-bang-ding","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0600-结构化绑定","结构化绑定",[7],"2000-0600",{"path":5350,"stem":5351,"title":5352,"authors":5353,"date":5068,"chapterOrder":5354,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0700-constexpr","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0700-constexpr","constexpr",[7],"2000-0700",{"path":5356,"stem":5357,"title":5358,"authors":5359,"date":5068,"chapterOrder":5360,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0800-raii","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0800-RAII","RAII",[7],"2000-0800",{"path":5362,"stem":5363,"title":5364,"authors":5365,"date":5068,"chapterOrder":5366,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0900-zhi-neng-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0900-智能指针","智能指针",[7],"2000-0900",{"path":5368,"stem":5369,"title":5370,"authors":5371,"date":5068,"chapterOrder":5372,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1000-you-zhi-yin-yong-he-yi-dong-yu-yi","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1000-右值引用和移动语义","右值引用和移动语义",[7],"2000-1000",{"path":5374,"stem":5375,"title":5376,"authors":5377,"date":5068,"chapterOrder":5378,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1100-lambda-biao-da-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1100-Lambda表达式","Lambda 表达式",[7],"2000-1100",{"path":5380,"stem":5381,"title":5382,"authors":5383,"date":5068,"chapterOrder":5384,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1200-std-function","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1200-std-function","std::function",[7],"2000-1200",{"path":5386,"stem":5387,"title":37,"authors":5388,"date":5068,"chapterOrder":5389,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1300-std-bind","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1300-std-bind",[7],"2000-1300",{"path":5391,"stem":5392,"title":5393,"authors":5394,"date":5068,"chapterOrder":5395,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1400-std-optional","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1400-std-optional","std::optional",[7],"2000-1400",{"path":5397,"stem":5398,"title":5399,"authors":5400,"date":5068,"chapterOrder":5401,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1500-std-variant","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1500-std-variant","std::variant",[7],"2000-1500",{"path":5403,"stem":5404,"title":5405,"authors":5406,"date":5068,"chapterOrder":5407,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1600-std-span","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1600-std-span","std::span",[7],"2000-1600",{"path":5409,"stem":5410,"title":5411,"authors":5412,"date":5068,"chapterOrder":5413,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1700-std-format-print","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1700-std-format-print","std::format \u002F std::print",[7],"2000-1700",{"path":5415,"stem":5416,"title":5417,"authors":5418,"date":5068,"chapterOrder":5419,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1800-std-chrono","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1800-std-chrono","std::chrono",[7],"2000-1800",{"path":5421,"stem":5422,"title":5423,"authors":5424,"date":5068,"chapterOrder":5425,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0100-bing-fa-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0100-并发是什么","并发是什么",[7],"2000-1900-0100",{"path":5427,"stem":5428,"title":5429,"authors":5430,"date":5068,"chapterOrder":5431,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0200-bing-xing-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0200-并行是什么","并行是什么",[7],"2000-1900-0200",{"path":5433,"stem":5434,"title":5435,"authors":5436,"date":5068,"chapterOrder":5437,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0300-xie-cheng-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0300-协程是什么","协程是什么",[7],"2000-1900-0300",{"path":5439,"stem":5440,"title":5441,"authors":5442,"date":5068,"chapterOrder":5443,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1000-bing-fa-bian-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1000-并发编程","并发编程",[7],"2000-1900-1000",{"path":5445,"stem":5446,"title":5447,"authors":5448,"date":5068,"chapterOrder":5449,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1100-std-thread","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1100-std-thread","std::thread",[7],"2000-1900-1100",{"path":5451,"stem":5452,"title":5453,"authors":5454,"date":5068,"chapterOrder":5455,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1200-mutex-lock-guard","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1200-mutex-lock-guard","mutex 与 RAII 锁",[7],"2000-1900-1200",{"path":5457,"stem":5458,"title":5459,"authors":5460,"date":5068,"chapterOrder":5461,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1300-std-atomic","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1300-std-atomic","std::atomic",[7],"2000-1900-1300",{"path":5463,"stem":5464,"title":5465,"authors":5466,"date":5068,"chapterOrder":5467,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1400-condition-variable","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1400-condition-variable","condition_variable",[7],"2000-1900-1400",{"path":5469,"stem":5470,"title":5471,"authors":5472,"date":5068,"chapterOrder":5473,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1500-future-async-promise","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1500-future-async-promise","future、async、promise 与 packaged_task",[7],"2000-1900-1500",{"path":5475,"stem":5476,"title":5477,"authors":5478,"date":5068,"chapterOrder":5479,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1600-jthread-stop-token","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1600-jthread-stop-token","jthread 与 stop_token",[7],"2000-1900-1600",{"path":5481,"stem":5482,"title":5483,"authors":5484,"date":5068,"chapterOrder":5485,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1700-semaphore-latch-barrier","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1700-semaphore-latch-barrier","semaphore、latch 与 barrier",[7],"2000-1900-1700",{"path":5487,"stem":5488,"title":5489,"authors":5490,"date":5068,"chapterOrder":5491,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-bing-fa-bing-xing-yu-xie-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-并发并行与协程","并发、并行与协程",[7],"2000-1900",{"path":5493,"stem":5494,"title":5495,"authors":5496,"date":5068,"chapterOrder":5497,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2000-std-filesystem","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-2000-std-filesystem","std::filesystem",[7],"2000-2000",{"path":5499,"stem":5500,"title":5501,"authors":5502,"date":5068,"chapterOrder":5503,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2100-modules-jian-jie","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-2100-modules简介","modules 简介",[7],"2000-2100",{"path":5505,"stem":5506,"title":5507,"authors":5508,"date":5068,"chapterOrder":5509,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-xian-dai-c","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-现代C++","现代C++",[7],"2000",{"path":5511,"stem":5512,"title":5513,"authors":5514,"date":5068,"chapterOrder":5515,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0100-ding-shi-qi-yu-yi-bu-io","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0100-定时器与异步IO","定时器与异步 IO",[7],"2100-0100-0100",{"path":5075,"stem":5077,"title":5,"authors":5517,"date":5068,"chapterOrder":5067,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},[7],{"path":5519,"stem":5520,"title":5521,"authors":5522,"date":5068,"chapterOrder":5523,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信","串口通信教学",[7],"2100-0100-0300",{"path":5525,"stem":5526,"title":5527,"authors":5528,"date":5068,"chapterOrder":5529,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0350-chuan-kou-tong-xin-chuan-kou-bao-xie-yi-shi-li","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0350-串口通信串口包协议实例","串口通信串口包协议实例",[7],"2100-0100-0350",{"path":5531,"stem":5532,"title":5533,"authors":5534,"date":5068,"chapterOrder":5535,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0400-tcp-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0400-TCP通信","TCP 通信",[7],"2100-0100-0400",{"path":5537,"stem":5538,"title":5539,"authors":5540,"date":5068,"chapterOrder":5541,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0500-udp-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0500-UDP通信","UDP 通信",[7],"2100-0100-0500",{"path":5543,"stem":5544,"title":5545,"authors":5546,"date":5068,"chapterOrder":5547,"chapterDepth":98,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0600-ji-qi-ren-gong-cheng-xie-fa-yu-ros2-ji-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0600-机器人工程写法与ROS2集成","机器人工程写法与 ROS2 集成",[7],"2100-0100-0600",{"path":5549,"stem":5550,"title":5551,"authors":5552,"date":5068,"chapterOrder":5553,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-boost-asio-yi-bu-io-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-Boost.Asio异步IO库","Boost.Asio异步IO库",[7],"2100-0100",{"path":5555,"stem":5556,"title":5557,"authors":5558,"date":5068,"chapterOrder":5559,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0200-eigen-xian-xing-dai-shu-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0200-Eigen线性代数库","Eigen线性代数库",[7],"2100-0200",{"path":5561,"stem":5562,"title":5563,"authors":5564,"date":5068,"chapterOrder":5565,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0300-opencv-ji-suan-ji-shi-jue-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0300-OpenCV计算机视觉库","OpenCV计算机视觉库",[7],"2100-0300",{"path":5567,"stem":5568,"title":5569,"authors":5570,"date":5068,"chapterOrder":5571,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0400-pcl-dian-yun-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0400-PCL点云库","PCL点云库",[7],"2100-0400",{"path":5573,"stem":5574,"title":5575,"authors":5576,"date":5068,"chapterOrder":5577,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0500-sophus-li-qun-li-dai-shu-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0500-Sophus李群李代数库","Sophus 李群李代数库",[7],"2100-0500",{"path":5579,"stem":5580,"title":5581,"authors":5582,"date":5068,"chapterOrder":5583,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-chang-yong-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-常用库","常用库学习",[7],"2100",{"path":5585,"stem":5586,"title":5587,"authors":5588,"date":5068,"chapterOrder":5589,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0100-cmakepresets-yu-gou-jian-an-zhuang","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0100-CMakePresets与构建安装","CMakePresets与构建安装",[7],"2200-0100",{"path":5591,"stem":5592,"title":5593,"authors":5594,"date":5068,"chapterOrder":5595,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0200-ding-ceng-cmake-yu-gong-gong-bian-yi-xuan-xiang","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0200-顶层CMake与公共编译选项","顶层CMake与公共编译选项",[7],"2200-0200",{"path":5597,"stem":5598,"title":5599,"authors":5600,"date":5068,"chapterOrder":5601,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0300-src-yu-lib-mo-kuai-cmake-xiang-jie","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0300-src与lib模块CMake详解","src与lib模块CMake详解",[7],"2200-0300",{"path":5603,"stem":5604,"title":5605,"authors":5606,"date":5068,"chapterOrder":5607,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0400-di-san-fang-ku-yi-lai-xie-fa","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0400-第三方库依赖写法","第三方库依赖写法",[7],"2200-0400",{"path":5609,"stem":5610,"title":5611,"authors":5612,"date":5068,"chapterOrder":5613,"chapterDepth":87,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0500-mu-ban-kuo-zhan-yu-chang-jian-wen-ti","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0500-模板扩展与常见问题","模板扩展与常见问题",[7],"2200-0500",{"path":5615,"stem":5616,"title":5617,"authors":5618,"date":5068,"chapterOrder":5619,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":5073},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-cmake-gong-cheng-mu-ban","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-CMake工程模板","CMake工程模板",[7],"2200",{"path":5070,"stem":5621,"title":5622,"authors":5623,"date":5068,"chapterOrder":5624,"chapterDepth":5086,"docKey":5069,"docRoot":5070,"docTitle":5071,"isWikiDoc":109,"isWikiIndex":109},"wiki\u002F2023-10-05-Cplusplus教学\u002Findex","C\u002FC++教程",[7],null,[5626,5628,5631,5634],{"name":7,"image":5627},"\u002Fimages\u002Fmember_photo\u002F董佳辉.jpg",{"name":5629,"image":5630},"宫金良","\u002Fimages\u002Fmember_photo\u002F宫金良.jpg",{"name":5632,"image":5633},"巩丽","\u002Fimages\u002Fmember_photo\u002F巩丽.png",{"name":5635,"image":5636},"张彦斐","\u002Fimages\u002Fmember_photo\u002F张彦斐.jpg",1792431899694]