[{"data":1,"prerenderedAt":2912},["ShallowReactive",2],{"wiki-page-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token":3,"wiki-doc-items-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token":2467,"language-switcher-data-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token":2896,"wiki-i18n-paths-\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token":2911},{"id":4,"title":5,"body":6,"canonicalPath":2449,"chapterDepth":219,"chapterOrder":2450,"date":2451,"description":12,"docI18nKey":2452,"docKey":2453,"docRoot":2454,"docTitle":2455,"extension":2456,"i18nKey":2457,"isBlogPost":2458,"isWikiDoc":230,"isWikiIndex":2458,"layout":2459,"legacyPath":2459,"locale":2460,"localeSlug":2461,"meta":2462,"navigation":230,"path":2449,"seo":2463,"sourcePath":2464,"sourceStem":2457,"stem":2465,"wikiDepth":27,"__hash__":2466},"content\u002F_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0600-jthread-stop-token.md","jthread 与 stop_token",{"type":7,"value":8,"toc":2412},"minimark",[9,13,36,43,54,59,75,85,93,99,126,129,145,148,162,168,185,192,199,202,320,323,335,341,344,351,356,362,365,373,376,379,384,389,394,399,402,408,413,418,423,426,685,688,700,706,713,716,730,733,736,739,752,755,762,767,781,784,790,797,803,809,812,815,843,850,854,857,905,914,920,923,930,934,937,972,975,987,990,993,998,1003,1008,1014,1019,1022,1052,1055,1069,1072,1075,1217,1220,1226,1232,1235,1246,1249,1252,1264,1266,1374,1379,1382,1389,1398,1400,1501,1504,1513,1519,1525,1534,1537,1541,1706,1709,1735,1738,1754,1761,1764,1793,1796,1816,1819,1822,1844,1851,1856,1869,1872,1875,1883,1892,1895,1907,1910,1912,2118,2121,2131,2179,2185,2188,2191,2197,2200,2205,2213,2216,2268,2271,2276,2282,2285,2287,2296,2304,2308,2317,2326,2331,2343,2348,2353,2357,2364,2371,2381,2386,2396,2408],[10,11,12],"p",{},"C++20 提供了：",[14,15,20],"pre",{"className":16,"code":17,"language":18,"meta":19,"style":19},"language-cpp shiki shiki-themes github-light github-dark","std::jthread\n","cpp","",[21,22,23],"code",{"__ignoreMap":19},[24,25,28,32],"span",{"class":26,"line":27},"line",1,[24,29,31],{"class":30},"sScJk","std",[24,33,35],{"class":34},"sVt8B","::jthread\n",[10,37,38,39,42],{},"它可以理解成“更安全的 ",[21,40,41],{},"std::thread","”：",[44,45,46],"ul",{},[47,48,49,50,53],"li",{},"析构时自动处理线程，不要求每条控制路径都手写 ",[21,51,52],{},"join()","；",[44,55,56],{},[47,57,58],{},"内置协作式停止机制；",[44,60,61],{},[47,62,63,64,67,68,67,71,74],{},"可以与 ",[21,65,66],{},"std::stop_token","、",[21,69,70],{},"std::stop_source",[21,72,73],{},"std::stop_callback"," 配合。",[10,76,77,78,81,82,84],{},"如果项目使用 C++20，并且线程是“启动后持续运行，退出时需要安全停止”的类型，",[21,79,80],{},"std::jthread"," 通常比裸 ",[21,83,41],{}," 更合适。",[86,87,89,90,92],"h2",{"id":88},"_1-stdthread-的生命周期风险","1. ",[21,91,41],{}," 的生命周期风险",[10,94,95,96,98],{},"使用 ",[21,97,41],{}," 时：",[14,100,102],{"className":16,"code":101,"language":18,"meta":19,"style":19},"std::thread t(work);\n",[21,103,104],{"__ignoreMap":19},[24,105,106,108,111,114,117,120,123],{"class":26,"line":27},[24,107,31],{"class":30},[24,109,110],{"class":34},"::",[24,112,113],{"class":30},"thread",[24,115,116],{"class":30}," t",[24,118,119],{"class":34},"(",[24,121,122],{"class":30},"work",[24,124,125],{"class":34},");\n",[10,127,128],{},"必须保证对象析构前已经：",[14,130,132],{"className":16,"code":131,"language":18,"meta":19,"style":19},"t.join();\n",[21,133,134],{"__ignoreMap":19},[24,135,136,139,142],{"class":26,"line":27},[24,137,138],{"class":34},"t.",[24,140,141],{"class":30},"join",[24,143,144],{"class":34},"();\n",[10,146,147],{},"或者：",[14,149,151],{"className":16,"code":150,"language":18,"meta":19,"style":19},"t.detach();\n",[21,152,153],{"__ignoreMap":19},[24,154,155,157,160],{"class":26,"line":27},[24,156,138],{"class":34},[24,158,159],{"class":30},"detach",[24,161,144],{"class":34},[10,163,164,165,167],{},"否则 joinable 的 ",[21,166,41],{}," 析构会调用：",[14,169,171],{"className":16,"code":170,"language":18,"meta":19,"style":19},"std::terminate()\n",[21,172,173],{"__ignoreMap":19},[24,174,175,177,179,182],{"class":26,"line":27},[24,176,31],{"class":30},[24,178,110],{"class":34},[24,180,181],{"class":30},"terminate",[24,183,184],{"class":34},"()\n",[10,186,187,188,191],{},"这意味着异常、提前 ",[21,189,190],{},"return","、复杂分支都可能让“是否已经 join”变成维护负担。",[86,193,195,196,198],{"id":194},"_2-stdjthread-会自动-join","2. ",[21,197,80],{}," 会自动 join",[10,200,201],{},"最简单的写法：",[14,203,205],{"className":16,"code":204,"language":18,"meta":19,"style":19},"#include \u003Ciostream>\n#include \u003Cthread>\n\nvoid work()\n{\n    std::cout \u003C\u003C \"working\\n\";\n}\n\nint main()\n{\n    std::jthread t(work);\n}\n",[21,206,207,217,225,232,243,249,274,280,285,296,301,315],{"__ignoreMap":19},[24,208,209,213],{"class":26,"line":27},[24,210,212],{"class":211},"szBVR","#include",[24,214,216],{"class":215},"sZZnC"," \u003Ciostream>\n",[24,218,220,222],{"class":26,"line":219},2,[24,221,212],{"class":211},[24,223,224],{"class":215}," \u003Cthread>\n",[24,226,228],{"class":26,"line":227},3,[24,229,231],{"emptyLinePlaceholder":230},true,"\n",[24,233,235,238,241],{"class":26,"line":234},4,[24,236,237],{"class":211},"void",[24,239,240],{"class":30}," work",[24,242,184],{"class":34},[24,244,246],{"class":26,"line":245},5,[24,247,248],{"class":34},"{\n",[24,250,252,255,258,261,264,268,271],{"class":26,"line":251},6,[24,253,254],{"class":30},"    std",[24,256,257],{"class":34},"::cout ",[24,259,260],{"class":211},"\u003C\u003C",[24,262,263],{"class":215}," \"working",[24,265,267],{"class":266},"sj4cs","\\n",[24,269,270],{"class":215},"\"",[24,272,273],{"class":34},";\n",[24,275,277],{"class":26,"line":276},7,[24,278,279],{"class":34},"}\n",[24,281,283],{"class":26,"line":282},8,[24,284,231],{"emptyLinePlaceholder":230},[24,286,288,291,294],{"class":26,"line":287},9,[24,289,290],{"class":211},"int",[24,292,293],{"class":30}," main",[24,295,184],{"class":34},[24,297,299],{"class":26,"line":298},10,[24,300,248],{"class":34},[24,302,304,306,309,312],{"class":26,"line":303},11,[24,305,254],{"class":30},[24,307,308],{"class":34},"::jthread ",[24,310,311],{"class":30},"t",[24,313,314],{"class":34},"(work);\n",[24,316,318],{"class":26,"line":317},12,[24,319,279],{"class":34},[10,321,322],{},"离开作用域时，不需要手动写：",[14,324,325],{"className":16,"code":131,"language":18,"meta":19,"style":19},[21,326,327],{"__ignoreMap":19},[24,328,329,331,333],{"class":26,"line":27},[24,330,138],{"class":34},[24,332,141],{"class":30},[24,334,144],{"class":34},[10,336,337,340],{},[21,338,339],{},"jthread"," 的析构函数会负责等待线程结束。",[10,342,343],{},"这让线程管理更符合 RAII 思想。",[86,345,347,348,350],{"id":346},"_3-jthread-不等于强制杀死线程","3. ",[21,349,339],{}," 不等于“强制杀死线程”",[10,352,353,355],{},[21,354,80],{}," 的停止机制是：",[357,358,359],"blockquote",{},[10,360,361],{},"协作式停止（cooperative cancellation）",[10,363,364],{},"In other words:",[14,366,371],{"className":367,"code":369,"language":370,"meta":19},[368],"language-text","某个线程发出停止请求\n       ↓\n工作线程主动检查这个请求\n       ↓\n工作线程自己决定在安全位置退出\n","text",[21,372,369],{"__ignoreMap":19},[10,374,375],{},"标准库不会粗暴地强制终止线程。",[10,377,378],{},"这是非常重要的设计，因为强制杀线程可能发生在：",[44,380,381],{},[47,382,383],{},"正持有 mutex；",[44,385,386],{},[47,387,388],{},"正修改对象状态；",[44,390,391],{},[47,392,393],{},"正写文件；",[44,395,396],{},[47,397,398],{},"正执行资源管理代码；",[10,400,401],{},"如果在任意位置突然中断，很容易破坏程序状态。",[86,403,405,406],{"id":404},"_4-stdstop_token","4. ",[21,407,66],{},[10,409,410,412],{},[21,411,66],{}," 表示：",[357,414,415],{},[10,416,417],{},"我可以观察某个停止请求是否已经发出。",[10,419,420,422],{},[21,421,339],{}," 可以自动把 stop token 作为线程函数的第一个参数传入。",[10,424,425],{},"For example:",[14,427,429],{"className":16,"code":428,"language":18,"meta":19,"style":19},"#include \u003Cchrono>\n#include \u003Ciostream>\n#include \u003Cstop_token>\n#include \u003Cthread>\n\nusing namespace std::chrono_literals;\n\nvoid worker(std::stop_token stop_token)\n{\n    while (!stop_token.stop_requested())\n    {\n        std::cout \u003C\u003C \"working\\n\";\n        std::this_thread::sleep_for(100ms);\n    }\n\n    std::cout \u003C\u003C \"stopping\\n\";\n}\n\nint main()\n{\n    std::jthread thread(worker);\n\n    std::this_thread::sleep_for(350ms);\n    thread.request_stop();\n}\n",[21,430,431,438,444,451,457,461,479,483,506,510,530,535,552,577,583,588,606,611,616,625,630,642,647,669,680],{"__ignoreMap":19},[24,432,433,435],{"class":26,"line":27},[24,434,212],{"class":211},[24,436,437],{"class":215}," \u003Cchrono>\n",[24,439,440,442],{"class":26,"line":219},[24,441,212],{"class":211},[24,443,216],{"class":215},[24,445,446,448],{"class":26,"line":227},[24,447,212],{"class":211},[24,449,450],{"class":215}," \u003Cstop_token>\n",[24,452,453,455],{"class":26,"line":234},[24,454,212],{"class":211},[24,456,224],{"class":215},[24,458,459],{"class":26,"line":245},[24,460,231],{"emptyLinePlaceholder":230},[24,462,463,466,469,472,474,477],{"class":26,"line":251},[24,464,465],{"class":211},"using",[24,467,468],{"class":211}," namespace",[24,470,471],{"class":30}," std",[24,473,110],{"class":34},[24,475,476],{"class":30},"chrono_literals",[24,478,273],{"class":34},[24,480,481],{"class":26,"line":276},[24,482,231],{"emptyLinePlaceholder":230},[24,484,485,487,490,492,494,496,499,503],{"class":26,"line":282},[24,486,237],{"class":211},[24,488,489],{"class":30}," worker",[24,491,119],{"class":34},[24,493,31],{"class":30},[24,495,110],{"class":34},[24,497,498],{"class":30},"stop_token",[24,500,502],{"class":501},"s4XuR"," stop_token",[24,504,505],{"class":34},")\n",[24,507,508],{"class":26,"line":287},[24,509,248],{"class":34},[24,511,512,515,518,521,524,527],{"class":26,"line":298},[24,513,514],{"class":211},"    while",[24,516,517],{"class":34}," (",[24,519,520],{"class":211},"!",[24,522,523],{"class":34},"stop_token.",[24,525,526],{"class":30},"stop_requested",[24,528,529],{"class":34},"())\n",[24,531,532],{"class":26,"line":303},[24,533,534],{"class":34},"    {\n",[24,536,537,540,542,544,546,548,550],{"class":26,"line":317},[24,538,539],{"class":30},"        std",[24,541,257],{"class":34},[24,543,260],{"class":211},[24,545,263],{"class":215},[24,547,267],{"class":266},[24,549,270],{"class":215},[24,551,273],{"class":34},[24,553,555,557,559,562,564,567,569,572,575],{"class":26,"line":554},13,[24,556,539],{"class":30},[24,558,110],{"class":34},[24,560,561],{"class":30},"this_thread",[24,563,110],{"class":34},[24,565,566],{"class":30},"sleep_for",[24,568,119],{"class":34},[24,570,571],{"class":266},"100",[24,573,574],{"class":211},"ms",[24,576,125],{"class":34},[24,578,580],{"class":26,"line":579},14,[24,581,582],{"class":34},"    }\n",[24,584,586],{"class":26,"line":585},15,[24,587,231],{"emptyLinePlaceholder":230},[24,589,591,593,595,597,600,602,604],{"class":26,"line":590},16,[24,592,254],{"class":30},[24,594,257],{"class":34},[24,596,260],{"class":211},[24,598,599],{"class":215}," \"stopping",[24,601,267],{"class":266},[24,603,270],{"class":215},[24,605,273],{"class":34},[24,607,609],{"class":26,"line":608},17,[24,610,279],{"class":34},[24,612,614],{"class":26,"line":613},18,[24,615,231],{"emptyLinePlaceholder":230},[24,617,619,621,623],{"class":26,"line":618},19,[24,620,290],{"class":211},[24,622,293],{"class":30},[24,624,184],{"class":34},[24,626,628],{"class":26,"line":627},20,[24,629,248],{"class":34},[24,631,633,635,637,639],{"class":26,"line":632},21,[24,634,254],{"class":30},[24,636,308],{"class":34},[24,638,113],{"class":30},[24,640,641],{"class":34},"(worker);\n",[24,643,645],{"class":26,"line":644},22,[24,646,231],{"emptyLinePlaceholder":230},[24,648,650,652,654,656,658,660,662,665,667],{"class":26,"line":649},23,[24,651,254],{"class":30},[24,653,110],{"class":34},[24,655,561],{"class":30},[24,657,110],{"class":34},[24,659,566],{"class":30},[24,661,119],{"class":34},[24,663,664],{"class":266},"350",[24,666,574],{"class":211},[24,668,125],{"class":34},[24,670,672,675,678],{"class":26,"line":671},24,[24,673,674],{"class":34},"    thread.",[24,676,677],{"class":30},"request_stop",[24,679,144],{"class":34},[24,681,683],{"class":26,"line":682},25,[24,684,279],{"class":34},[10,686,687],{},"这里线程函数的第一个参数：",[14,689,691],{"className":16,"code":690,"language":18,"meta":19,"style":19},"std::stop_token\n",[21,692,693],{"__ignoreMap":19},[24,694,695,697],{"class":26,"line":27},[24,696,31],{"class":30},[24,698,699],{"class":34},"::stop_token\n",[10,701,702,703,705],{},"由 ",[21,704,339],{}," 自动提供，不需要调用者手动传。",[86,707,709,710],{"id":708},"_5-request_stop","5. ",[21,711,712],{},"request_stop()",[10,714,715],{},"调用：",[14,717,719],{"className":16,"code":718,"language":18,"meta":19,"style":19},"thread.request_stop();\n",[21,720,721],{"__ignoreMap":19},[24,722,723,726,728],{"class":26,"line":27},[24,724,725],{"class":34},"thread.",[24,727,677],{"class":30},[24,729,144],{"class":34},[10,731,732],{},"只是“发出停止请求”。",[10,734,735],{},"它不会等待线程结束，也不会强制终止线程。",[10,737,738],{},"工作线程需要主动检查：",[14,740,742],{"className":16,"code":741,"language":18,"meta":19,"style":19},"stop_token.stop_requested()\n",[21,743,744],{"__ignoreMap":19},[24,745,746,748,750],{"class":26,"line":27},[24,747,523],{"class":34},[24,749,526],{"class":30},[24,751,184],{"class":34},[10,753,754],{},"并自行退出。",[86,756,758,759],{"id":757},"_6-stop_possible","6. ",[21,760,761],{},"stop_possible()",[10,763,764,766],{},[21,765,498],{}," 还可以查询：",[14,768,770],{"className":16,"code":769,"language":18,"meta":19,"style":19},"stop_token.stop_possible()\n",[21,771,772],{"__ignoreMap":19},[24,773,774,776,779],{"class":26,"line":27},[24,775,523],{"class":34},[24,777,778],{"class":30},"stop_possible",[24,780,184],{"class":34},[10,782,783],{},"表示这个 token 是否关联着一个能够产生停止请求的停止状态。",[10,785,786,787,789],{},"普通 ",[21,788,339],{}," 自动提供的 token 通常是可停止的。",[86,791,793,794,796],{"id":792},"_7-jthread-析构时会发生什么","7. ",[21,795,339],{}," 析构时会发生什么",[10,798,799,800,802],{},"如果一个 ",[21,801,339],{}," 在析构时仍然 joinable，析构过程概念上会：",[14,804,807],{"className":805,"code":806,"language":370,"meta":19},[368],"request_stop()\n      ↓\njoin()\n",[21,808,806],{"__ignoreMap":19},[10,810,811],{},"也就是说，它不只是自动等待，还会先请求线程停止。",[10,813,814],{},"因此：",[14,816,818],{"className":16,"code":817,"language":18,"meta":19,"style":19},"{\n    std::jthread thread(worker);\n} \u002F\u002F 离开作用域时自动请求停止并等待结束\n",[21,819,820,824,834],{"__ignoreMap":19},[24,821,822],{"class":26,"line":27},[24,823,248],{"class":34},[24,825,826,828,830,832],{"class":26,"line":219},[24,827,254],{"class":30},[24,829,308],{"class":34},[24,831,113],{"class":30},[24,833,641],{"class":34},[24,835,836,839],{"class":26,"line":227},[24,837,838],{"class":34},"}",[24,840,842],{"class":841},"sJ8bj"," \u002F\u002F 离开作用域时自动请求停止并等待结束\n",[10,844,845,846,849],{},"如果 ",[21,847,848],{},"worker"," 正确响应 stop token，就能自然退出。",[86,851,853],{"id":852},"_8-析构请求停止不等于一定能立刻退出","8. 析构请求停止不等于一定能立刻退出",[10,855,856],{},"如果工作线程完全不检查 stop token：",[14,858,860],{"className":16,"code":859,"language":18,"meta":19,"style":19},"void worker(std::stop_token)\n{\n    while (true)\n    {\n    }\n}\n",[21,861,862,878,882,893,897,901],{"__ignoreMap":19},[24,863,864,866,868,870,872,874,876],{"class":26,"line":27},[24,865,237],{"class":211},[24,867,489],{"class":30},[24,869,119],{"class":34},[24,871,31],{"class":30},[24,873,110],{"class":34},[24,875,498],{"class":30},[24,877,505],{"class":34},[24,879,880],{"class":26,"line":219},[24,881,248],{"class":34},[24,883,884,886,888,891],{"class":26,"line":227},[24,885,514],{"class":211},[24,887,517],{"class":34},[24,889,890],{"class":266},"true",[24,892,505],{"class":34},[24,894,895],{"class":26,"line":234},[24,896,534],{"class":34},[24,898,899],{"class":26,"line":245},[24,900,582],{"class":34},[24,902,903],{"class":26,"line":251},[24,904,279],{"class":34},[10,906,907,908,910,911,913],{},"那么 ",[21,909,339],{}," 析构时虽然调用了 ",[21,912,712],{},"，线程依然不会退出。",[10,915,916,917,919],{},"随后析构中的 ",[21,918,52],{}," 会一直等待。",[10,921,922],{},"So:",[357,924,925],{},[10,926,927,929],{},[21,928,339],{}," 提供停止协议，但线程函数必须主动合作。",[86,931,933],{"id":932},"_9-阻塞操作也要考虑停止","9. 阻塞操作也要考虑停止",[10,935,936],{},"下面虽然检查了停止请求：",[14,938,940],{"className":16,"code":939,"language":18,"meta":19,"style":19},"while (!stop_token.stop_requested())\n{\n    blocking_operation();\n}\n",[21,941,942,957,961,968],{"__ignoreMap":19},[24,943,944,947,949,951,953,955],{"class":26,"line":27},[24,945,946],{"class":211},"while",[24,948,517],{"class":34},[24,950,520],{"class":211},[24,952,523],{"class":34},[24,954,526],{"class":30},[24,956,529],{"class":34},[24,958,959],{"class":26,"line":219},[24,960,248],{"class":34},[24,962,963,966],{"class":26,"line":227},[24,964,965],{"class":30},"    blocking_operation",[24,967,144],{"class":34},[24,969,970],{"class":26,"line":234},[24,971,279],{"class":34},[10,973,974],{},"但如果：",[14,976,978],{"className":16,"code":977,"language":18,"meta":19,"style":19},"blocking_operation()\n",[21,979,980],{"__ignoreMap":19},[24,981,982,985],{"class":26,"line":27},[24,983,984],{"class":30},"blocking_operation",[24,986,184],{"class":34},[10,988,989],{},"一次就能阻塞几十秒，那么停止响应仍然会非常慢。",[10,991,992],{},"线程设计不仅要考虑“有没有 stop token”，还要考虑：",[44,994,995],{},[47,996,997],{},"阻塞调用是否支持超时；",[44,999,1000],{},[47,1001,1002],{},"是否能被唤醒；",[44,1004,1005],{},[47,1006,1007],{},"是否可以分阶段检查停止状态。",[86,1009,1011,1012],{"id":1010},"_10-stdstop_source","10. ",[21,1013,70],{},[10,1015,1016,1018],{},[21,1017,70],{}," 是停止请求的“控制端”。",[10,1020,1021],{},"可以：",[14,1023,1025],{"className":16,"code":1024,"language":18,"meta":19,"style":19},"std::stop_source source;\nstd::stop_token token = source.get_token();\n",[21,1026,1027,1034],{"__ignoreMap":19},[24,1028,1029,1031],{"class":26,"line":27},[24,1030,31],{"class":30},[24,1032,1033],{"class":34},"::stop_source source;\n",[24,1035,1036,1038,1041,1044,1047,1050],{"class":26,"line":219},[24,1037,31],{"class":30},[24,1039,1040],{"class":34},"::stop_token token ",[24,1042,1043],{"class":211},"=",[24,1045,1046],{"class":34}," source.",[24,1048,1049],{"class":30},"get_token",[24,1051,144],{"class":34},[10,1053,1054],{},"然后：",[14,1056,1058],{"className":16,"code":1057,"language":18,"meta":19,"style":19},"source.request_stop();\n",[21,1059,1060],{"__ignoreMap":19},[24,1061,1062,1065,1067],{"class":26,"line":27},[24,1063,1064],{"class":34},"source.",[24,1066,677],{"class":30},[24,1068,144],{"class":34},[10,1070,1071],{},"所有关联到这个停止状态的 token 都能观察到请求。",[10,1073,1074],{},"Example:",[14,1076,1078],{"className":16,"code":1077,"language":18,"meta":19,"style":19},"#include \u003Ciostream>\n#include \u003Cstop_token>\n\nint main()\n{\n    std::stop_source source;\n    std::stop_token token = source.get_token();\n\n    std::cout \u003C\u003C std::boolalpha\n              \u003C\u003C token.stop_requested()\n              \u003C\u003C '\\n';\n\n    source.request_stop();\n\n    std::cout \u003C\u003C token.stop_requested() \u003C\u003C '\\n';\n}\n",[21,1079,1080,1086,1092,1096,1104,1108,1114,1128,1132,1145,1157,1171,1175,1184,1188,1213],{"__ignoreMap":19},[24,1081,1082,1084],{"class":26,"line":27},[24,1083,212],{"class":211},[24,1085,216],{"class":215},[24,1087,1088,1090],{"class":26,"line":219},[24,1089,212],{"class":211},[24,1091,450],{"class":215},[24,1093,1094],{"class":26,"line":227},[24,1095,231],{"emptyLinePlaceholder":230},[24,1097,1098,1100,1102],{"class":26,"line":234},[24,1099,290],{"class":211},[24,1101,293],{"class":30},[24,1103,184],{"class":34},[24,1105,1106],{"class":26,"line":245},[24,1107,248],{"class":34},[24,1109,1110,1112],{"class":26,"line":251},[24,1111,254],{"class":30},[24,1113,1033],{"class":34},[24,1115,1116,1118,1120,1122,1124,1126],{"class":26,"line":276},[24,1117,254],{"class":30},[24,1119,1040],{"class":34},[24,1121,1043],{"class":211},[24,1123,1046],{"class":34},[24,1125,1049],{"class":30},[24,1127,144],{"class":34},[24,1129,1130],{"class":26,"line":282},[24,1131,231],{"emptyLinePlaceholder":230},[24,1133,1134,1136,1138,1140,1142],{"class":26,"line":287},[24,1135,254],{"class":30},[24,1137,257],{"class":34},[24,1139,260],{"class":211},[24,1141,471],{"class":30},[24,1143,1144],{"class":34},"::boolalpha\n",[24,1146,1147,1150,1153,1155],{"class":26,"line":298},[24,1148,1149],{"class":211},"              \u003C\u003C",[24,1151,1152],{"class":34}," token.",[24,1154,526],{"class":30},[24,1156,184],{"class":34},[24,1158,1159,1161,1164,1166,1169],{"class":26,"line":303},[24,1160,1149],{"class":211},[24,1162,1163],{"class":215}," '",[24,1165,267],{"class":266},[24,1167,1168],{"class":215},"'",[24,1170,273],{"class":34},[24,1172,1173],{"class":26,"line":317},[24,1174,231],{"emptyLinePlaceholder":230},[24,1176,1177,1180,1182],{"class":26,"line":554},[24,1178,1179],{"class":34},"    source.",[24,1181,677],{"class":30},[24,1183,144],{"class":34},[24,1185,1186],{"class":26,"line":579},[24,1187,231],{"emptyLinePlaceholder":230},[24,1189,1190,1192,1194,1196,1198,1200,1203,1205,1207,1209,1211],{"class":26,"line":585},[24,1191,254],{"class":30},[24,1193,257],{"class":34},[24,1195,260],{"class":211},[24,1197,1152],{"class":34},[24,1199,526],{"class":30},[24,1201,1202],{"class":34},"() ",[24,1204,260],{"class":211},[24,1206,1163],{"class":215},[24,1208,267],{"class":266},[24,1210,1168],{"class":215},[24,1212,273],{"class":34},[24,1214,1215],{"class":26,"line":590},[24,1216,279],{"class":34},[10,1218,1219],{},"输出：",[14,1221,1224],{"className":1222,"code":1223,"language":370,"meta":19},[368],"false\ntrue\n",[21,1225,1223],{"__ignoreMap":19},[86,1227,1229,1230],{"id":1228},"_11-stdstop_callback","11. ",[21,1231,73],{},[10,1233,1234],{},"有时不希望某个线程一直轮询：",[14,1236,1238],{"className":16,"code":1237,"language":18,"meta":19,"style":19},"stop_requested()\n",[21,1239,1240],{"__ignoreMap":19},[24,1241,1242,1244],{"class":26,"line":27},[24,1243,526],{"class":30},[24,1245,184],{"class":34},[10,1247,1248],{},"而是希望停止请求到来时自动执行一段回调。",[10,1250,1251],{},"可以使用：",[14,1253,1255],{"className":16,"code":1254,"language":18,"meta":19,"style":19},"std::stop_callback\n",[21,1256,1257],{"__ignoreMap":19},[24,1258,1259,1261],{"class":26,"line":27},[24,1260,31],{"class":30},[24,1262,1263],{"class":34},"::stop_callback\n",[10,1265,425],{},[14,1267,1269],{"className":16,"code":1268,"language":18,"meta":19,"style":19},"#include \u003Ciostream>\n#include \u003Cstop_token>\n\nint main()\n{\n    std::stop_source source;\n    std::stop_token token = source.get_token();\n\n    std::stop_callback callback(token, [] {\n        std::cout \u003C\u003C \"stop requested\\n\";\n    });\n\n    source.request_stop();\n}\n",[21,1270,1271,1277,1283,1287,1295,1299,1305,1319,1323,1336,1353,1358,1362,1370],{"__ignoreMap":19},[24,1272,1273,1275],{"class":26,"line":27},[24,1274,212],{"class":211},[24,1276,216],{"class":215},[24,1278,1279,1281],{"class":26,"line":219},[24,1280,212],{"class":211},[24,1282,450],{"class":215},[24,1284,1285],{"class":26,"line":227},[24,1286,231],{"emptyLinePlaceholder":230},[24,1288,1289,1291,1293],{"class":26,"line":234},[24,1290,290],{"class":211},[24,1292,293],{"class":30},[24,1294,184],{"class":34},[24,1296,1297],{"class":26,"line":245},[24,1298,248],{"class":34},[24,1300,1301,1303],{"class":26,"line":251},[24,1302,254],{"class":30},[24,1304,1033],{"class":34},[24,1306,1307,1309,1311,1313,1315,1317],{"class":26,"line":276},[24,1308,254],{"class":30},[24,1310,1040],{"class":34},[24,1312,1043],{"class":211},[24,1314,1046],{"class":34},[24,1316,1049],{"class":30},[24,1318,144],{"class":34},[24,1320,1321],{"class":26,"line":282},[24,1322,231],{"emptyLinePlaceholder":230},[24,1324,1325,1327,1330,1333],{"class":26,"line":287},[24,1326,254],{"class":30},[24,1328,1329],{"class":34},"::stop_callback ",[24,1331,1332],{"class":30},"callback",[24,1334,1335],{"class":34},"(token, [] {\n",[24,1337,1338,1340,1342,1344,1347,1349,1351],{"class":26,"line":298},[24,1339,539],{"class":30},[24,1341,257],{"class":34},[24,1343,260],{"class":211},[24,1345,1346],{"class":215}," \"stop requested",[24,1348,267],{"class":266},[24,1350,270],{"class":215},[24,1352,273],{"class":34},[24,1354,1355],{"class":26,"line":303},[24,1356,1357],{"class":34},"    });\n",[24,1359,1360],{"class":26,"line":317},[24,1361,231],{"emptyLinePlaceholder":230},[24,1363,1364,1366,1368],{"class":26,"line":554},[24,1365,1179],{"class":34},[24,1367,677],{"class":30},[24,1369,144],{"class":34},[24,1371,1372],{"class":26,"line":579},[24,1373,279],{"class":34},[10,1375,1376,1378],{},[21,1377,712],{}," 发出停止请求时，已注册的 callback 会执行。",[10,1380,1381],{},"注意 callback 的执行上下文与停止请求有关，因此回调本身也应该保持简单，并避免制造新的锁顺序问题。",[86,1383,1385,1386,1388],{"id":1384},"_12-jthread-也支持普通线程函数","12. ",[21,1387,339],{}," 也支持普通线程函数",[10,1390,1391,1392,1394,1395,1397],{},"并不是所有 ",[21,1393,339],{}," 函数都必须接收 ",[21,1396,498],{},"。",[10,1399,425],{},[14,1401,1403],{"className":16,"code":1402,"language":18,"meta":19,"style":19},"#include \u003Ciostream>\n#include \u003Cthread>\n\nvoid work(int value)\n{\n    std::cout \u003C\u003C value \u003C\u003C '\\n';\n}\n\nint main()\n{\n    std::jthread thread(work, 42);\n}\n",[21,1404,1405,1411,1417,1421,1436,1440,1461,1465,1469,1477,1481,1497],{"__ignoreMap":19},[24,1406,1407,1409],{"class":26,"line":27},[24,1408,212],{"class":211},[24,1410,216],{"class":215},[24,1412,1413,1415],{"class":26,"line":219},[24,1414,212],{"class":211},[24,1416,224],{"class":215},[24,1418,1419],{"class":26,"line":227},[24,1420,231],{"emptyLinePlaceholder":230},[24,1422,1423,1425,1427,1429,1431,1434],{"class":26,"line":234},[24,1424,237],{"class":211},[24,1426,240],{"class":30},[24,1428,119],{"class":34},[24,1430,290],{"class":211},[24,1432,1433],{"class":501}," value",[24,1435,505],{"class":34},[24,1437,1438],{"class":26,"line":245},[24,1439,248],{"class":34},[24,1441,1442,1444,1446,1448,1451,1453,1455,1457,1459],{"class":26,"line":251},[24,1443,254],{"class":30},[24,1445,257],{"class":34},[24,1447,260],{"class":211},[24,1449,1450],{"class":34}," value ",[24,1452,260],{"class":211},[24,1454,1163],{"class":215},[24,1456,267],{"class":266},[24,1458,1168],{"class":215},[24,1460,273],{"class":34},[24,1462,1463],{"class":26,"line":276},[24,1464,279],{"class":34},[24,1466,1467],{"class":26,"line":282},[24,1468,231],{"emptyLinePlaceholder":230},[24,1470,1471,1473,1475],{"class":26,"line":287},[24,1472,290],{"class":211},[24,1474,293],{"class":30},[24,1476,184],{"class":34},[24,1478,1479],{"class":26,"line":298},[24,1480,248],{"class":34},[24,1482,1483,1485,1487,1489,1492,1495],{"class":26,"line":303},[24,1484,254],{"class":30},[24,1486,308],{"class":34},[24,1488,113],{"class":30},[24,1490,1491],{"class":34},"(work, ",[24,1493,1494],{"class":266},"42",[24,1496,125],{"class":34},[24,1498,1499],{"class":26,"line":317},[24,1500,279],{"class":34},[10,1502,1503],{},"如果可调用对象能够以：",[14,1505,1507],{"className":16,"code":1506,"language":18,"meta":19,"style":19},"(stop_token, args...)\n",[21,1508,1509],{"__ignoreMap":19},[24,1510,1511],{"class":26,"line":27},[24,1512,1506],{"class":34},[10,1514,1515,1516,1518],{},"形式调用，",[21,1517,339],{}," 会优先传入 stop token。",[10,1520,1521,1522,1524],{},"否则就像普通 ",[21,1523,113],{}," 一样使用：",[14,1526,1528],{"className":16,"code":1527,"language":18,"meta":19,"style":19},"(args...)\n",[21,1529,1530],{"__ignoreMap":19},[24,1531,1532],{"class":26,"line":27},[24,1533,1527],{"class":34},[10,1535,1536],{},"形式调用。",[86,1538,1540],{"id":1539},"_13-带参数的-stop-token-线程函数","13. 带参数的 stop token 线程函数",[14,1542,1544],{"className":16,"code":1543,"language":18,"meta":19,"style":19},"#include \u003Ciostream>\n#include \u003Cstop_token>\n#include \u003Cthread>\n\nvoid worker(std::stop_token token, int id)\n{\n    std::cout \u003C\u003C \"worker \" \u003C\u003C id \u003C\u003C '\\n';\n\n    while (!token.stop_requested())\n    {\n        \u002F\u002F work\n    }\n}\n\nint main()\n{\n    std::jthread thread(worker, 7);\n    thread.request_stop();\n}\n",[21,1545,1546,1552,1558,1564,1568,1595,1599,1626,1630,1645,1649,1654,1658,1662,1666,1674,1678,1694,1702],{"__ignoreMap":19},[24,1547,1548,1550],{"class":26,"line":27},[24,1549,212],{"class":211},[24,1551,216],{"class":215},[24,1553,1554,1556],{"class":26,"line":219},[24,1555,212],{"class":211},[24,1557,450],{"class":215},[24,1559,1560,1562],{"class":26,"line":227},[24,1561,212],{"class":211},[24,1563,224],{"class":215},[24,1565,1566],{"class":26,"line":234},[24,1567,231],{"emptyLinePlaceholder":230},[24,1569,1570,1572,1574,1576,1578,1580,1582,1585,1588,1590,1593],{"class":26,"line":245},[24,1571,237],{"class":211},[24,1573,489],{"class":30},[24,1575,119],{"class":34},[24,1577,31],{"class":30},[24,1579,110],{"class":34},[24,1581,498],{"class":30},[24,1583,1584],{"class":501}," token",[24,1586,1587],{"class":34},", ",[24,1589,290],{"class":211},[24,1591,1592],{"class":501}," id",[24,1594,505],{"class":34},[24,1596,1597],{"class":26,"line":251},[24,1598,248],{"class":34},[24,1600,1601,1603,1605,1607,1610,1613,1616,1618,1620,1622,1624],{"class":26,"line":276},[24,1602,254],{"class":30},[24,1604,257],{"class":34},[24,1606,260],{"class":211},[24,1608,1609],{"class":215}," \"worker \"",[24,1611,1612],{"class":211}," \u003C\u003C",[24,1614,1615],{"class":34}," id ",[24,1617,260],{"class":211},[24,1619,1163],{"class":215},[24,1621,267],{"class":266},[24,1623,1168],{"class":215},[24,1625,273],{"class":34},[24,1627,1628],{"class":26,"line":282},[24,1629,231],{"emptyLinePlaceholder":230},[24,1631,1632,1634,1636,1638,1641,1643],{"class":26,"line":287},[24,1633,514],{"class":211},[24,1635,517],{"class":34},[24,1637,520],{"class":211},[24,1639,1640],{"class":34},"token.",[24,1642,526],{"class":30},[24,1644,529],{"class":34},[24,1646,1647],{"class":26,"line":298},[24,1648,534],{"class":34},[24,1650,1651],{"class":26,"line":303},[24,1652,1653],{"class":841},"        \u002F\u002F work\n",[24,1655,1656],{"class":26,"line":317},[24,1657,582],{"class":34},[24,1659,1660],{"class":26,"line":554},[24,1661,279],{"class":34},[24,1663,1664],{"class":26,"line":579},[24,1665,231],{"emptyLinePlaceholder":230},[24,1667,1668,1670,1672],{"class":26,"line":585},[24,1669,290],{"class":211},[24,1671,293],{"class":30},[24,1673,184],{"class":34},[24,1675,1676],{"class":26,"line":590},[24,1677,248],{"class":34},[24,1679,1680,1682,1684,1686,1689,1692],{"class":26,"line":608},[24,1681,254],{"class":30},[24,1683,308],{"class":34},[24,1685,113],{"class":30},[24,1687,1688],{"class":34},"(worker, ",[24,1690,1691],{"class":266},"7",[24,1693,125],{"class":34},[24,1695,1696,1698,1700],{"class":26,"line":613},[24,1697,674],{"class":34},[24,1699,677],{"class":30},[24,1701,144],{"class":34},[24,1703,1704],{"class":26,"line":618},[24,1705,279],{"class":34},[10,1707,1708],{},"这里：",[14,1710,1712],{"className":16,"code":1711,"language":18,"meta":19,"style":19},"std::jthread thread(worker, 7);\n",[21,1713,1714],{"__ignoreMap":19},[24,1715,1716,1718,1720,1722,1725,1727,1729,1731,1733],{"class":26,"line":27},[24,1717,31],{"class":30},[24,1719,110],{"class":34},[24,1721,339],{"class":30},[24,1723,1724],{"class":30}," thread",[24,1726,119],{"class":34},[24,1728,848],{"class":30},[24,1730,1587],{"class":34},[24,1732,1691],{"class":266},[24,1734,125],{"class":34},[10,1736,1737],{},"调用效果相当于让线程执行：",[14,1739,1741],{"className":16,"code":1740,"language":18,"meta":19,"style":19},"worker(自动提供的 stop_token, 7)\n",[21,1742,1743],{"__ignoreMap":19},[24,1744,1745,1747,1750,1752],{"class":26,"line":27},[24,1746,848],{"class":30},[24,1748,1749],{"class":34},"(自动提供的 stop_token, ",[24,1751,1691],{"class":266},[24,1753,505],{"class":34},[86,1755,1757,1758,1760],{"id":1756},"_14-jthread-同样可以-join","14. ",[21,1759,339],{}," 同样可以 join",[10,1762,1763],{},"自动 join 不代表不能手动 join。",[14,1765,1767],{"className":16,"code":1766,"language":18,"meta":19,"style":19},"std::jthread thread(work);\nthread.join();\n",[21,1768,1769,1785],{"__ignoreMap":19},[24,1770,1771,1773,1775,1777,1779,1781,1783],{"class":26,"line":27},[24,1772,31],{"class":30},[24,1774,110],{"class":34},[24,1776,339],{"class":30},[24,1778,1724],{"class":30},[24,1780,119],{"class":34},[24,1782,122],{"class":30},[24,1784,125],{"class":34},[24,1786,1787,1789,1791],{"class":26,"line":219},[24,1788,725],{"class":34},[24,1790,141],{"class":30},[24,1792,144],{"class":34},[10,1794,1795],{},"调用后：",[14,1797,1799],{"className":16,"code":1798,"language":18,"meta":19,"style":19},"thread.joinable() == false\n",[21,1800,1801],{"__ignoreMap":19},[24,1802,1803,1805,1808,1810,1813],{"class":26,"line":27},[24,1804,725],{"class":34},[24,1806,1807],{"class":30},"joinable",[24,1809,1202],{"class":34},[24,1811,1812],{"class":211},"==",[24,1814,1815],{"class":266}," false\n",[10,1817,1818],{},"之后析构时就无需再次等待。",[10,1820,1821],{},"同样可以查询：",[14,1823,1825],{"className":16,"code":1824,"language":18,"meta":19,"style":19},"thread.joinable()\nthread.get_id()\n",[21,1826,1827,1835],{"__ignoreMap":19},[24,1828,1829,1831,1833],{"class":26,"line":27},[24,1830,725],{"class":34},[24,1832,1807],{"class":30},[24,1834,184],{"class":34},[24,1836,1837,1839,1842],{"class":26,"line":219},[24,1838,725],{"class":34},[24,1840,1841],{"class":30},"get_id",[24,1843,184],{"class":34},[86,1845,1847,1848,1850],{"id":1846},"_15-jthread-也可以-detach但通常不推荐","15. ",[21,1849,339],{}," 也可以 detach，但通常不推荐",[10,1852,1853,1855],{},[21,1854,339],{}," 仍然提供：",[14,1857,1859],{"className":16,"code":1858,"language":18,"meta":19,"style":19},"thread.detach();\n",[21,1860,1861],{"__ignoreMap":19},[24,1862,1863,1865,1867],{"class":26,"line":27},[24,1864,725],{"class":34},[24,1866,159],{"class":30},[24,1868,144],{"class":34},[10,1870,1871],{},"但一旦 detach，RAII 自动等待和结构化停止的优势就基本失去了。",[10,1873,1874],{},"除非确实明确理解生命周期，否则不要为了“后台运行”轻易 detach。",[86,1876,1878,1879,1882],{"id":1877},"_16-condition_variable_any-与-stop-token","16. ",[21,1880,1881],{},"condition_variable_any"," 与 stop token",[10,1884,786,1885,1888,1889,1891],{},[21,1886,1887],{},"std::condition_variable"," 没有直接接收 ",[21,1890,498],{}," 的等待重载。",[10,1893,1894],{},"C++20 的：",[14,1896,1898],{"className":16,"code":1897,"language":18,"meta":19,"style":19},"std::condition_variable_any\n",[21,1899,1900],{"__ignoreMap":19},[24,1901,1902,1904],{"class":26,"line":27},[24,1903,31],{"class":30},[24,1905,1906],{"class":34},"::condition_variable_any\n",[10,1908,1909],{},"则可以把停止请求整合进等待条件。",[10,1911,425],{},[14,1913,1915],{"className":16,"code":1914,"language":18,"meta":19,"style":19},"#include \u003Ccondition_variable>\n#include \u003Cmutex>\n#include \u003Cstop_token>\n#include \u003Cthread>\n\nstd::mutex mutex;\nstd::condition_variable_any cv;\nbool ready = false;\n\nvoid worker(std::stop_token token)\n{\n    std::unique_lock lock(mutex);\n\n    bool condition_met = cv.wait(\n        lock,\n        token,\n        [] {\n            return ready;\n        });\n\n    if (!condition_met)\n    {\n        \u002F\u002F 因停止请求结束等待\n        return;\n    }\n\n    \u002F\u002F ready == true\n}\n",[21,1916,1917,1924,1931,1937,1943,1947,1954,1961,1976,1980,1998,2002,2015,2019,2038,2043,2048,2053,2061,2066,2070,2082,2086,2091,2098,2102,2107,2113],{"__ignoreMap":19},[24,1918,1919,1921],{"class":26,"line":27},[24,1920,212],{"class":211},[24,1922,1923],{"class":215}," \u003Ccondition_variable>\n",[24,1925,1926,1928],{"class":26,"line":219},[24,1927,212],{"class":211},[24,1929,1930],{"class":215}," \u003Cmutex>\n",[24,1932,1933,1935],{"class":26,"line":227},[24,1934,212],{"class":211},[24,1936,450],{"class":215},[24,1938,1939,1941],{"class":26,"line":234},[24,1940,212],{"class":211},[24,1942,224],{"class":215},[24,1944,1945],{"class":26,"line":245},[24,1946,231],{"emptyLinePlaceholder":230},[24,1948,1949,1951],{"class":26,"line":251},[24,1950,31],{"class":30},[24,1952,1953],{"class":34},"::mutex mutex;\n",[24,1955,1956,1958],{"class":26,"line":276},[24,1957,31],{"class":30},[24,1959,1960],{"class":34},"::condition_variable_any cv;\n",[24,1962,1963,1966,1969,1971,1974],{"class":26,"line":282},[24,1964,1965],{"class":211},"bool",[24,1967,1968],{"class":34}," ready ",[24,1970,1043],{"class":211},[24,1972,1973],{"class":266}," false",[24,1975,273],{"class":34},[24,1977,1978],{"class":26,"line":287},[24,1979,231],{"emptyLinePlaceholder":230},[24,1981,1982,1984,1986,1988,1990,1992,1994,1996],{"class":26,"line":298},[24,1983,237],{"class":211},[24,1985,489],{"class":30},[24,1987,119],{"class":34},[24,1989,31],{"class":30},[24,1991,110],{"class":34},[24,1993,498],{"class":30},[24,1995,1584],{"class":501},[24,1997,505],{"class":34},[24,1999,2000],{"class":26,"line":303},[24,2001,248],{"class":34},[24,2003,2004,2006,2009,2012],{"class":26,"line":317},[24,2005,254],{"class":30},[24,2007,2008],{"class":34},"::unique_lock ",[24,2010,2011],{"class":30},"lock",[24,2013,2014],{"class":34},"(mutex);\n",[24,2016,2017],{"class":26,"line":554},[24,2018,231],{"emptyLinePlaceholder":230},[24,2020,2021,2024,2027,2029,2032,2035],{"class":26,"line":579},[24,2022,2023],{"class":211},"    bool",[24,2025,2026],{"class":34}," condition_met ",[24,2028,1043],{"class":211},[24,2030,2031],{"class":34}," cv.",[24,2033,2034],{"class":30},"wait",[24,2036,2037],{"class":34},"(\n",[24,2039,2040],{"class":26,"line":585},[24,2041,2042],{"class":34},"        lock,\n",[24,2044,2045],{"class":26,"line":590},[24,2046,2047],{"class":34},"        token,\n",[24,2049,2050],{"class":26,"line":608},[24,2051,2052],{"class":34},"        [] {\n",[24,2054,2055,2058],{"class":26,"line":613},[24,2056,2057],{"class":211},"            return",[24,2059,2060],{"class":34}," ready;\n",[24,2062,2063],{"class":26,"line":618},[24,2064,2065],{"class":34},"        });\n",[24,2067,2068],{"class":26,"line":627},[24,2069,231],{"emptyLinePlaceholder":230},[24,2071,2072,2075,2077,2079],{"class":26,"line":632},[24,2073,2074],{"class":211},"    if",[24,2076,517],{"class":34},[24,2078,520],{"class":211},[24,2080,2081],{"class":34},"condition_met)\n",[24,2083,2084],{"class":26,"line":644},[24,2085,534],{"class":34},[24,2087,2088],{"class":26,"line":649},[24,2089,2090],{"class":841},"        \u002F\u002F 因停止请求结束等待\n",[24,2092,2093,2096],{"class":26,"line":671},[24,2094,2095],{"class":211},"        return",[24,2097,273],{"class":34},[24,2099,2100],{"class":26,"line":682},[24,2101,582],{"class":34},[24,2103,2105],{"class":26,"line":2104},26,[24,2106,231],{"emptyLinePlaceholder":230},[24,2108,2110],{"class":26,"line":2109},27,[24,2111,2112],{"class":841},"    \u002F\u002F ready == true\n",[24,2114,2116],{"class":26,"line":2115},28,[24,2117,279],{"class":34},[10,2119,2120],{},"这样线程在等待条件时也能响应停止请求，不必额外写一个轮询循环。",[86,2122,2124,2125,2127,2128,2130],{"id":2123},"_17-thread-和-jthread-对比","17. ",[21,2126,113],{}," 和 ",[21,2129,339],{}," 对比",[2132,2133,2134,2154],"table",{},[2135,2136,2137],"thead",{},[2138,2139,2140,2145,2150],"tr",{},[2141,2142,2144],"th",{"align":2143},"left","Features",[2141,2146,2148],{"align":2147},"center",[21,2149,41],{},[2141,2151,2152],{"align":2147},[21,2153,80],{},[2155,2156,2157,2169],"tbody",{},[2138,2158,2159,2163,2166],{},[2160,2161,2162],"td",{"align":2143},"Standard version",[2160,2164,2165],{"align":2147},"C++11",[2160,2167,2168],{"align":2147},"C++20",[2138,2170,2171,2174,2177],{},[2160,2172,2173],{"align":2143},"创建线程",[2160,2175,2176],{"align":2147},"✅",[2160,2178,2176],{"align":2147},[10,2180,2181,2182,2184],{},"|Manual ",[21,2183,52],{},"|✅|✅|\n|析构自动等待|❌|✅|",[10,2186,2187],{},"|析构时 joinable 会 terminate|✅|❌|",[10,2189,2190],{},"|内置停止请求|❌|✅|",[10,2192,2193,2194,2196],{},"|自动传 ",[21,2195,498],{},"|❌|✅|",[10,2198,2199],{},"|可 detach|✅|✅|",[10,2201,2202,2203,1397],{},"如果环境允许使用 C++20，新写的“可停止后台线程”通常优先考虑 ",[21,2204,339],{},[86,2206,2208,2209,2212],{"id":2207},"_18-atomicbool-running-和-stop-token-怎么选","18. ",[21,2210,2211],{},"atomic\u003Cbool> running"," 和 stop token 怎么选",[10,2214,2215],{},"传统写法：",[14,2217,2219],{"className":16,"code":2218,"language":18,"meta":19,"style":19},"std::atomic\u003Cbool> running{true};\n\nwhile (running.load())\n{\n    ...\n}\n",[21,2220,2221,2239,2243,2255,2259,2264],{"__ignoreMap":19},[24,2222,2223,2225,2228,2231,2234,2236],{"class":26,"line":27},[24,2224,31],{"class":30},[24,2226,2227],{"class":34},"::atomic",[24,2229,2230],{"class":211},"\u003Cbool>",[24,2232,2233],{"class":34}," running{",[24,2235,890],{"class":266},[24,2237,2238],{"class":34},"};\n",[24,2240,2241],{"class":26,"line":219},[24,2242,231],{"emptyLinePlaceholder":230},[24,2244,2245,2247,2250,2253],{"class":26,"line":227},[24,2246,946],{"class":211},[24,2248,2249],{"class":34}," (running.",[24,2251,2252],{"class":30},"load",[24,2254,529],{"class":34},[24,2256,2257],{"class":26,"line":234},[24,2258,248],{"class":34},[24,2260,2261],{"class":26,"line":245},[24,2262,2263],{"class":34},"    ...\n",[24,2265,2266],{"class":26,"line":251},[24,2267,279],{"class":34},[10,2269,2270],{},"仍然完全合法，而且在简单场景下很直观。",[10,2272,2273,2275],{},[21,2274,498],{}," 的优势是把：",[14,2277,2280],{"className":2278,"code":2279,"language":370,"meta":19},[368],"停止请求\n停止观察\n停止回调\njthread 生命周期\n",[21,2281,2279],{"__ignoreMap":19},[10,2283,2284],{},"组织成标准协议。",[10,2286,814],{},[44,2288,2289],{},[47,2290,2291,2292,2295],{},"只需要一个非常简单的原子标志：",[21,2293,2294],{},"atomic\u003Cbool>"," 仍然很好用；",[44,2297,2298],{},[47,2299,2300,2301,1397],{},"线程本身有明确的“请求停止”生命周期：优先考虑 ",[21,2302,2303],{},"jthread + stop_token",[86,2305,2307],{"id":2306},"_19-常见错误","19. 常见错误",[2309,2310,2311],"ol",{},[47,2312,2313,2314,2316],{},"以为 ",[21,2315,712],{}," 会强制杀死线程。",[2309,2318,2319],{"start":219},[47,2320,2321,2322,2325],{},"工作函数从不检查 ",[21,2323,2324],{},"stop_requested()","，导致析构仍然一直等待。",[2309,2327,2328],{"start":227},[47,2329,2330],{},"在线程内部执行长时间不可中断阻塞操作，导致停止响应很慢。",[2309,2332,2333],{"start":234},[47,2334,2335,2336,2338,2339,2342],{},"使用了 ",[21,2337,339],{}," 却仍然随手 ",[21,2340,2341],{},"detach()","，失去 RAII 生命周期管理优势。",[2309,2344,2345],{"start":245},[47,2346,2347],{},"stop callback 内执行复杂阻塞逻辑或获取大量锁，导致停止路径本身难以控制。",[2309,2349,2350],{"start":251},[47,2351,2352],{},"把“收到停止请求”理解成“必须立即在任意位置退出”，而不是在安全点协作退出。",[86,2354,2356],{"id":2355},"summary","Summary",[44,2358,2359],{},[47,2360,2361,2363],{},[21,2362,80],{}," 是 C++20 更现代的线程管理类。",[44,2365,2366],{},[47,2367,2368,2370],{},[21,2369,339],{}," 析构时会对 joinable 线程请求停止并等待结束。",[44,2372,2373],{},[47,2374,2375,2377,2378,2380],{},[21,2376,66],{}," 用来观察停止请求，",[21,2379,712],{}," 只是请求，不是强制终止。",[44,2382,2383],{},[47,2384,2385],{},"停止必须由工作线程协作响应。",[44,2387,2388],{},[47,2389,2390,2392,2393,2395],{},[21,2391,70],{}," 是请求端，",[21,2394,73],{}," 可以在请求发生时执行回调。",[44,2397,2398],{},[47,2399,2400,2401,2403,2404,2407],{},"对需要明确停止协议的后台线程，",[21,2402,2303],{}," 通常比 ",[21,2405,2406],{},"thread + atomic\u003Cbool>"," 更结构化。",[2409,2410,2411],"style",{},"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 .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 .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 .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":19,"searchDepth":219,"depth":219,"links":2413},[2414,2416,2418,2420,2422,2424,2426,2428,2429,2430,2432,2434,2436,2437,2439,2441,2443,2445,2447,2448],{"id":88,"depth":219,"text":2415},"1. std::thread 的生命周期风险",{"id":194,"depth":219,"text":2417},"2. std::jthread 会自动 join",{"id":346,"depth":219,"text":2419},"3. jthread 不等于“强制杀死线程”",{"id":404,"depth":219,"text":2421},"4. std::stop_token",{"id":708,"depth":219,"text":2423},"5. request_stop()",{"id":757,"depth":219,"text":2425},"6. stop_possible()",{"id":792,"depth":219,"text":2427},"7. jthread 析构时会发生什么",{"id":852,"depth":219,"text":853},{"id":932,"depth":219,"text":933},{"id":1010,"depth":219,"text":2431},"10. std::stop_source",{"id":1228,"depth":219,"text":2433},"11. std::stop_callback",{"id":1384,"depth":219,"text":2435},"12. jthread 也支持普通线程函数",{"id":1539,"depth":219,"text":1540},{"id":1756,"depth":219,"text":2438},"14. jthread 同样可以 join",{"id":1846,"depth":219,"text":2440},"15. jthread 也可以 detach，但通常不推荐",{"id":1877,"depth":219,"text":2442},"16. condition_variable_any 与 stop token",{"id":2123,"depth":219,"text":2444},"17. thread 和 jthread 对比",{"id":2207,"depth":219,"text":2446},"18. atomic\u003Cbool> running 和 stop token 怎么选",{"id":2306,"depth":219,"text":2307},{"id":2355,"depth":219,"text":2356},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","2000-1900-0600","2023-10-05","wiki\u002F2023-10-05-cplusplus-jiao-xue","en-us:2023-10-05-cplusplus-jiao-xue","\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue","Cplusplus教学","md","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0600-jthread-stop-token",false,null,"en-US","en-us",{},{"title":5,"description":12},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0600-jthread-stop-token","zBIvyqilZfLe6GU6LhdAfriwgDu7JCakoJWoe5par7o",[2468,2474,2479,2484,2489,2494,2499,2504,2509,2514,2519,2524,2529,2534,2539,2544,2549,2554,2559,2564,2569,2574,2579,2584,2589,2594,2599,2604,2609,2614,2619,2624,2629,2634,2639,2644,2649,2654,2659,2664,2669,2674,2678,2683,2688,2693,2698,2703,2708,2713,2718,2723,2728,2733,2738,2743,2748,2753,2757,2762,2767,2772,2777,2778,2783,2788,2793,2798,2803,2808,2813,2818,2823,2828,2833,2838,2843,2848,2853,2858,2863,2868,2873,2878,2883,2888,2893],{"path":2469,"stem":2470,"title":2471,"date":2451,"chapterOrder":2472,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0100-c-kai-fa-huan-jing-da-jian-yu-ce-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0100-C++开发环境搭建与测试","C++ Development Environment Setup and Testing","0100",0,{"path":2475,"stem":2476,"title":2477,"date":2451,"chapterOrder":2478,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0200-c-ji-chu-chu-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0200-C++基础初识","C++ Basics","0200",{"path":2480,"stem":2481,"title":2482,"date":2451,"chapterOrder":2483,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0300-shu-ju-lei-xing-yu-shu-ju-cun-fang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0300-数据类型与数据存放","Data Types and Data Storage","0300",{"path":2485,"stem":2486,"title":2487,"date":2451,"chapterOrder":2488,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0400-shu-ru-shu-chu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0400-输入输出","Input and Output","0400",{"path":2490,"stem":2491,"title":2492,"date":2451,"chapterOrder":2493,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0500-yun-suan-fu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0500-运算符","operator","0500",{"path":2495,"stem":2496,"title":2497,"date":2451,"chapterOrder":2498,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0600-cheng-xu-liu-cheng-jie-gou","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0600-程序流程结构","program flow structure","0600",{"path":2500,"stem":2501,"title":2502,"date":2451,"chapterOrder":2503,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0700-shu-zu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0700-数组","array","0700",{"path":2505,"stem":2506,"title":2507,"date":2451,"chapterOrder":2508,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0800-han-shu-yu-tou-wen-jian","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0800-函数与头文件","Functions and Header Files","0800",{"path":2510,"stem":2511,"title":2512,"date":2451,"chapterOrder":2513,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0900-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F0900-指针","pointer","0900",{"path":2515,"stem":2516,"title":2517,"date":2451,"chapterOrder":2518,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1000-jie-gou-ti-yu-gong-yong-ti","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1000-结构体与共用体","Structures and Unions","1000",{"path":2520,"stem":2521,"title":2522,"date":2451,"chapterOrder":2523,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1100-nei-cun-fen-qu-yu-sheng-ming-zhou-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1100-内存分区与生命周期","Memory Partitioning and Lifecycle","1100",{"path":2525,"stem":2526,"title":2527,"date":2451,"chapterOrder":2528,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1200-yin-yong","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1200-引用","reference","1200",{"path":2530,"stem":2531,"title":2532,"date":2451,"chapterOrder":2533,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1300-han-shu-ti-gao","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1300-函数提高","Function Optimization","1300",{"path":2535,"stem":2536,"title":2537,"date":2451,"chapterOrder":2538,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1350-ming-ming-kong-jian","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1350-命名空间","命名空间","1350",{"path":2540,"stem":2541,"title":2542,"date":2451,"chapterOrder":2543,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0100-feng-zhuang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0100-封装","encapsulation","1400-0100",{"path":2545,"stem":2546,"title":2547,"date":2451,"chapterOrder":2548,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0200-dui-xiang-chu-shi-hua-he-qing-li","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0200-对象初始化和清理","Object initialization and cleanup","1400-0200",{"path":2550,"stem":2551,"title":2552,"date":2451,"chapterOrder":2553,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0300-dui-xiang-mo-xing-yu-this-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0300-对象模型与this指针","Object Model and the `this` Pointer","1400-0300",{"path":2555,"stem":2556,"title":2557,"date":2451,"chapterOrder":2558,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0400-you-yuan-yu-yun-suan-fu-zhong-zai","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0400-友元与运算符重载","Friends and operator overloading","1400-0400",{"path":2560,"stem":2561,"title":2562,"date":2451,"chapterOrder":2563,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0500-ji-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0500-继承","inheritance","1400-0500",{"path":2565,"stem":2566,"title":2567,"date":2451,"chapterOrder":2568,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0600-duo-tai","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-0600-多态","polymorphism","1400-0600",{"path":2570,"stem":2571,"title":2572,"date":2451,"chapterOrder":2573,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-lei-he-dui-xiang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1400-类和对象","Classes and Objects","1400",{"path":2575,"stem":2576,"title":2577,"date":2451,"chapterOrder":2578,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1450-han-shu-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1450-函数指针","function pointer","1450",{"path":2580,"stem":2581,"title":2582,"date":2451,"chapterOrder":2583,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1500-wen-jian-cao-zuo","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1500-文件操作","File operations","1500",{"path":2585,"stem":2586,"title":2587,"date":2451,"chapterOrder":2588,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1600-yi-chang-chu-li-yu-cuo-wu-ma","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1600-异常处理与错误码","异常处理","1600",{"path":2590,"stem":2591,"title":2592,"date":2451,"chapterOrder":2593,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1700-mu-ban","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1700-模板","template","1700",{"path":2595,"stem":2596,"title":2597,"date":2451,"chapterOrder":2598,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0100-stl-chu-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0100-STL初识","Introduction to STL","1800-0100",{"path":2600,"stem":2601,"title":2602,"date":2451,"chapterOrder":2603,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0200-std-array","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0200-std-array","std::array","1800-0200",{"path":2605,"stem":2606,"title":2607,"date":2451,"chapterOrder":2608,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0300-string-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0300-string容器","string container","1800-0300",{"path":2610,"stem":2611,"title":2612,"date":2451,"chapterOrder":2613,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0400-vector-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0400-vector容器","vector 容器","1800-0400",{"path":2615,"stem":2616,"title":2617,"date":2451,"chapterOrder":2618,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0500-deque-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0500-deque容器","deque 容器","1800-0500",{"path":2620,"stem":2621,"title":2622,"date":2451,"chapterOrder":2623,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0600-stack-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0600-stack容器","stack 容器","1800-0600",{"path":2625,"stem":2626,"title":2627,"date":2451,"chapterOrder":2628,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0700-queue-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0700-queue容器","queue container","1800-0700",{"path":2630,"stem":2631,"title":2632,"date":2451,"chapterOrder":2633,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0800-list-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0800-list容器","list 容器","1800-0800",{"path":2635,"stem":2636,"title":2637,"date":2451,"chapterOrder":2638,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0900-set-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-0900-set容器","set \u002F multiset 容器","1800-0900",{"path":2640,"stem":2641,"title":2642,"date":2451,"chapterOrder":2643,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1000-map-rong-qi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1000-map容器","map \u002F multimap 容器","1800-1000",{"path":2645,"stem":2646,"title":2647,"date":2451,"chapterOrder":2648,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1100-han-shu-dui-xiang-yu-wei-ci","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1100-函数对象与谓词","Function objects and predicates","1800-1100",{"path":2650,"stem":2651,"title":2652,"date":2451,"chapterOrder":2653,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1200-chang-yong-suan-fa","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-1200-常用算法","Common algorithms","1800-1200",{"path":2655,"stem":2656,"title":2657,"date":2451,"chapterOrder":2658,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-stl-ti-gao-bian-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1800-STL提高编程","Level up your programming with STL.","1800",{"path":2660,"stem":2661,"title":2662,"date":2451,"chapterOrder":2663,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1900-c-lei-xing-zhuan-huan","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F1900-C++类型转换","C++ Type Casting","1900",{"path":2665,"stem":2666,"title":2667,"date":2451,"chapterOrder":2668,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0100-auto","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0100-auto","auto","2000-0100",{"path":2670,"stem":2671,"title":2672,"date":2451,"chapterOrder":2673,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0200-nullptr","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0200-nullptr","nullptr","2000-0200",{"path":2675,"stem":2676,"title":465,"date":2451,"chapterOrder":2677,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0300-using","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0300-using","2000-0300",{"path":2679,"stem":2680,"title":2681,"date":2451,"chapterOrder":2682,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0400-enum-class","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0400-enum-class","enum class","2000-0400",{"path":2684,"stem":2685,"title":2686,"date":2451,"chapterOrder":2687,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0500-fan-wei-for-xun-huan","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0500-范围for循环","range-based for loop","2000-0500",{"path":2689,"stem":2690,"title":2691,"date":2451,"chapterOrder":2692,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0600-jie-gou-hua-bang-ding","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0600-结构化绑定","structured binding","2000-0600",{"path":2694,"stem":2695,"title":2696,"date":2451,"chapterOrder":2697,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0700-constexpr","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0700-constexpr","constexpr","2000-0700",{"path":2699,"stem":2700,"title":2701,"date":2451,"chapterOrder":2702,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0800-raii","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0800-RAII","RAII","2000-0800",{"path":2704,"stem":2705,"title":2706,"date":2451,"chapterOrder":2707,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0900-zhi-neng-zhi-zhen","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-0900-智能指针","Smart pointer","2000-0900",{"path":2709,"stem":2710,"title":2711,"date":2451,"chapterOrder":2712,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1000-you-zhi-yin-yong-he-yi-dong-yu-yi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1000-右值引用和移动语义","Rvalue references and move semantics","2000-1000",{"path":2714,"stem":2715,"title":2716,"date":2451,"chapterOrder":2717,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1100-lambda-biao-da-shi","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1100-Lambda表达式","Lambda expression","2000-1100",{"path":2719,"stem":2720,"title":2721,"date":2451,"chapterOrder":2722,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1200-std-function","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1200-std-function","std::function","2000-1200",{"path":2724,"stem":2725,"title":2726,"date":2451,"chapterOrder":2727,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1300-std-bind","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1300-std-bind","std::bind","2000-1300",{"path":2729,"stem":2730,"title":2731,"date":2451,"chapterOrder":2732,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1400-std-optional","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1400-std-optional","std::optional","2000-1400",{"path":2734,"stem":2735,"title":2736,"date":2451,"chapterOrder":2737,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1500-std-variant","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1500-std-variant","std::variant","2000-1500",{"path":2739,"stem":2740,"title":2741,"date":2451,"chapterOrder":2742,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1600-std-span","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1600-std-span","std::span","2000-1600",{"path":2744,"stem":2745,"title":2746,"date":2451,"chapterOrder":2747,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1700-std-format-print","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1700-std-format-print","std::format \u002F std::print","2000-1700",{"path":2749,"stem":2750,"title":2751,"date":2451,"chapterOrder":2752,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1800-std-chrono","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1800-std-chrono","std::chrono","2000-1800",{"path":2754,"stem":2755,"title":41,"date":2451,"chapterOrder":2756,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0100-std-thread","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0100-std-thread","2000-1900-0100",{"path":2758,"stem":2759,"title":2760,"date":2451,"chapterOrder":2761,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0200-mutex-lock-guard","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0200-mutex-lock-guard","mutex 与 RAII 锁","2000-1900-0200",{"path":2763,"stem":2764,"title":2765,"date":2451,"chapterOrder":2766,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0300-std-atomic","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0300-std-atomic","std::atomic","2000-1900-0300",{"path":2768,"stem":2769,"title":2770,"date":2451,"chapterOrder":2771,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0400-condition-variable","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0400-condition-variable","condition_variable","2000-1900-0400",{"path":2773,"stem":2774,"title":2775,"date":2451,"chapterOrder":2776,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0500-future-async-promise","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0500-future-async-promise","future、async、promise 与 packaged_task","2000-1900-0500",{"path":2449,"stem":2465,"title":5,"date":2451,"chapterOrder":2450,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},{"path":2779,"stem":2780,"title":2781,"date":2451,"chapterOrder":2782,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0700-semaphore-latch-barrier","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0700-semaphore-latch-barrier","semaphore、latch 与 barrier","2000-1900-0700",{"path":2784,"stem":2785,"title":2786,"date":2451,"chapterOrder":2787,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-bing-fa-bian-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-并发编程","Concurrent programming","2000-1900",{"path":2789,"stem":2790,"title":2791,"date":2451,"chapterOrder":2792,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2000-std-filesystem","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-2000-std-filesystem","std::filesystem","2000-2000",{"path":2794,"stem":2795,"title":2796,"date":2451,"chapterOrder":2797,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2100-modules-jian-jie","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-2100-modules简介","Modules Introduction","2000-2100",{"path":2799,"stem":2800,"title":2801,"date":2451,"chapterOrder":2802,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-xian-dai-c","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-现代C++","Modern C++","2000",{"path":2804,"stem":2805,"title":2806,"date":2451,"chapterOrder":2807,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0100-ding-shi-qi-yu-yi-bu-io","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0100-定时器与异步IO","Timers and Asynchronous I\u002FO","2100-0100-0100",{"path":2809,"stem":2810,"title":2811,"date":2451,"chapterOrder":2812,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0200-boost-asio-ji-chu","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0200-Boost.Asio基础","Boost.Asio Basics","2100-0100-0200",{"path":2814,"stem":2815,"title":2816,"date":2451,"chapterOrder":2817,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信","serial communication","2100-0100-0300",{"path":2819,"stem":2820,"title":2821,"date":2451,"chapterOrder":2822,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0400-tcp-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0400-TCP通信","TCP communication","2100-0100-0400",{"path":2824,"stem":2825,"title":2826,"date":2451,"chapterOrder":2827,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0500-udp-tong-xin","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0500-UDP通信","UDP communication","2100-0100-0500",{"path":2829,"stem":2830,"title":2831,"date":2451,"chapterOrder":2832,"chapterDepth":219,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0600-ji-qi-ren-gong-cheng-xie-fa-yu-ros2-ji-cheng","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0600-机器人工程写法与ROS2集成","Robot Engineering Approach and ROS2 Integration","2100-0100-0600",{"path":2834,"stem":2835,"title":2836,"date":2451,"chapterOrder":2837,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-boost-asio-yi-bu-io-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-Boost.Asio异步IO库","Boost.Asio asynchronous IO library","2100-0100",{"path":2839,"stem":2840,"title":2841,"date":2451,"chapterOrder":2842,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0200-eigen-xian-xing-dai-shu-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0200-Eigen线性代数库","Eigen linear algebra library","2100-0200",{"path":2844,"stem":2845,"title":2846,"date":2451,"chapterOrder":2847,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0300-opencv-ji-suan-ji-shi-jue-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0300-OpenCV计算机视觉库","OpenCV Computer Vision Library","2100-0300",{"path":2849,"stem":2850,"title":2851,"date":2451,"chapterOrder":2852,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0400-pcl-dian-yun-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0400-PCL点云库","PCL Point Cloud Library","2100-0400",{"path":2854,"stem":2855,"title":2856,"date":2451,"chapterOrder":2857,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0500-sophus-li-qun-li-dai-shu-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-0500-Sophus李群李代数库","Sophus Lie group and Lie algebra library","2100-0500",{"path":2859,"stem":2860,"title":2861,"date":2451,"chapterOrder":2862,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-chang-yong-ku","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2100-常用库","Learning Common Libraries","2100",{"path":2864,"stem":2865,"title":2866,"date":2451,"chapterOrder":2867,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0100-cmakepresets-yu-gou-jian-an-zhuang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0100-CMakePresets与构建安装","CMakePresets and Build Installation","2200-0100",{"path":2869,"stem":2870,"title":2871,"date":2451,"chapterOrder":2872,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0200-ding-ceng-cmake-yu-gong-gong-bian-yi-xuan-xiang","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0200-顶层CMake与公共编译选项","Top-level CMake and Public Compilation Options","2200-0200",{"path":2874,"stem":2875,"title":2876,"date":2451,"chapterOrder":2877,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0300-src-yu-lib-mo-kuai-cmake-xiang-jie","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0300-src与lib模块CMake详解","Detailed CMake Explanation for src and lib Modules","2200-0300",{"path":2879,"stem":2880,"title":2881,"date":2451,"chapterOrder":2882,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0400-di-san-fang-ku-yi-lai-xie-fa","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0400-第三方库依赖写法","How to write third-party library dependencies","2200-0400",{"path":2884,"stem":2885,"title":2886,"date":2451,"chapterOrder":2887,"chapterDepth":27,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0500-mu-ban-kuo-zhan-yu-chang-jian-wen-ti","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-0500-模板扩展与常见问题","Template Extensions and FAQ","2200-0500",{"path":2889,"stem":2890,"title":2891,"date":2451,"chapterOrder":2892,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":2458},"\u002Fen-us\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-cmake-gong-cheng-mu-ban","_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2200-CMake工程模板","CMake Project Template","2200",{"path":2454,"stem":2894,"title":2895,"date":2451,"chapterOrder":2459,"chapterDepth":2473,"docKey":2453,"docRoot":2454,"docTitle":2455,"isWikiDoc":230,"isWikiIndex":230},"_i18n\u002Fen-us\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002Findex","C\u002FC++ tutorial",{"variants":2897},[2898,2899,2902,2905,2908],{"path":2449,"localeSlug":2461,"i18nKey":2457},{"path":2900,"localeSlug":2901,"i18nKey":2457},"\u002Fzh-hant\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","zh-hant",{"path":2903,"localeSlug":2904,"i18nKey":2457},"\u002Fzh-hk\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","zh-hk",{"path":2906,"localeSlug":2907,"i18nKey":2457},"\u002Fzh-tw\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","zh-tw",{"path":2909,"localeSlug":2910,"i18nKey":2457},"\u002Fzh-cn\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0600-jthread-stop-token","zh-cn",[2449,2464,2900,2464,2903,2464,2906,2464,2909,2464],1789198804200]