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