[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess":2923,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess":2949},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2919,"stem":2920,"id":2921,"extension":2922},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess","进程与子进程","Node.js 在单个进程中运行，但通过 process 对象、child_process 模块及 worker_threads 模块提供了对进程的精细控制以及多进程\u002F多线程能力。下面从三个方面展开。","技能小册",[12,13],"nodejs","process","2023-11-10",false,{"type":17,"value":18,"toc":2907},"minimark",[19,22,27,43,51,56,65,68,174,181,184,203,264,275,287,308,403,410,425,501,511,528,599,606,609,665,672,675,701,725,735,742,761,855,863,1089,1096,1359,1366,1373,1526,1532,1624,1633,1637,1671,1675,1841,1845,1866,1872,1875,1879,1885,2140,2146,2404,2411,2423,2724,2731,2829,2832,2866,2869,2900,2903],[20,21,8],"h1",{"id":8},[23,24,26],"h2",{"id":25},"nodejs-进程与子进程详解","Node.js 进程与子进程详解",[28,29,30,31,34,35,38,39,42],"p",{},"Node.js 在单个进程中运行，但通过 ",[32,33,13],"code",{}," 对象、",[32,36,37],{},"child_process"," 模块及 ",[32,40,41],{},"worker_threads"," 模块提供了对进程的精细控制以及多进程\u002F多线程能力。下面从三个方面展开。",[44,45,47,48,50],"h3",{"id":46},"一process-对象","一、",[32,49,13],{}," 对象",[28,52,53,55],{},[32,54,13],{}," 对象是全局对象，提供当前 Node.js 进程的信息和控制能力。",[57,58,60,61,64],"h4",{"id":59},"_1-环境变量processenv","1. 环境变量（",[32,62,63],{},"process.env","）",[28,66,67],{},"返回包含用户环境变量的对象。可读取、修改或删除环境变量，但修改仅在当前进程中生效，不影响父进程。",[69,70,75],"pre",{"className":71,"code":72,"language":73,"meta":74,"style":74},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","console.log(process.env.NODE_ENV); \u002F\u002F 打印环境变量\nprocess.env.MY_VAR = \"hello\"; \u002F\u002F 设置临时变量\ndelete process.env.MY_VAR; \u002F\u002F 删除\n","js","",[32,76,77,118,152],{"__ignoreMap":74},[78,79,82,86,90,94,97,99,102,104,108,111,114],"span",{"class":80,"line":81},"line",1,[78,83,85],{"class":84},"su5hD","console",[78,87,89],{"class":88},"sP7_E",".",[78,91,93],{"class":92},"sGLFI","log",[78,95,96],{"class":84},"(process",[78,98,89],{"class":88},[78,100,101],{"class":84},"env",[78,103,89],{"class":88},[78,105,107],{"class":106},"s_hVV","NODE_ENV",[78,109,110],{"class":84},")",[78,112,113],{"class":88},";",[78,115,117],{"class":116},"sutJx"," \u002F\u002F 打印环境变量\n",[78,119,121,123,125,127,129,132,136,140,144,147,149],{"class":80,"line":120},2,[78,122,13],{"class":84},[78,124,89],{"class":88},[78,126,101],{"class":84},[78,128,89],{"class":88},[78,130,131],{"class":106},"MY_VAR",[78,133,135],{"class":134},"smGrS"," =",[78,137,139],{"class":138},"sjJ54"," \"",[78,141,143],{"class":142},"s_sjI","hello",[78,145,146],{"class":138},"\"",[78,148,113],{"class":88},[78,150,151],{"class":116}," \u002F\u002F 设置临时变量\n",[78,153,155,158,161,163,165,167,169,171],{"class":80,"line":154},3,[78,156,157],{"class":134},"delete",[78,159,160],{"class":84}," process",[78,162,89],{"class":88},[78,164,101],{"class":84},[78,166,89],{"class":88},[78,168,131],{"class":106},[78,170,113],{"class":88},[78,172,173],{"class":116}," \u002F\u002F 删除\n",[57,175,177,178,64],{"id":176},"_2-命令行参数processargv","2. 命令行参数（",[32,179,180],{},"process.argv",[28,182,183],{},"返回数组，包含启动 Node.js 进程时的命令行参数：",[185,186,187,194,200],"ul",{},[188,189,190,193],"li",{},[32,191,192],{},"argv[0]","：Node.js 可执行文件路径",[188,195,196,199],{},[32,197,198],{},"argv[1]","：当前执行的 JavaScript 文件路径",[188,201,202],{},"后续元素为用户传入的参数",[69,204,206],{"className":71,"code":205,"language":73,"meta":74,"style":74},"\u002F\u002F node app.js --name=John --age 30\nconst args = process.argv.slice(2);\nconsole.log(args); \u002F\u002F ['--name=John', '--age', '30']\n",[32,207,208,213,248],{"__ignoreMap":74},[78,209,210],{"class":80,"line":81},[78,211,212],{"class":116},"\u002F\u002F node app.js --name=John --age 30\n",[78,214,215,219,222,224,226,228,231,233,236,239,243,245],{"class":80,"line":120},[78,216,218],{"class":217},"sbsja","const",[78,220,221],{"class":106}," args",[78,223,135],{"class":134},[78,225,160],{"class":84},[78,227,89],{"class":88},[78,229,230],{"class":84},"argv",[78,232,89],{"class":88},[78,234,235],{"class":92},"slice",[78,237,238],{"class":84},"(",[78,240,242],{"class":241},"srdBf","2",[78,244,110],{"class":84},[78,246,247],{"class":88},";\n",[78,249,250,252,254,256,259,261],{"class":80,"line":154},[78,251,85],{"class":84},[78,253,89],{"class":88},[78,255,93],{"class":92},[78,257,258],{"class":84},"(args)",[78,260,113],{"class":88},[78,262,263],{"class":116}," \u002F\u002F ['--name=John', '--age', '30']\n",[28,265,266,267,270,271,274],{},"常用第三方库如 ",[32,268,269],{},"minimist"," 或 ",[32,272,273],{},"commander"," 可简化解析。",[57,276,278,279,282,283,286],{"id":277},"_3-退出processexit-与-exit-事件","3. 退出（",[32,280,281],{},"process.exit"," 与 ",[32,284,285],{},"exit"," 事件）",[185,288,289,302],{},[188,290,291,294,295,297,298,301],{},[32,292,293],{},"process.exit([code])","：终止进程，默认 ",[32,296,32],{}," 为 ",[32,299,300],{},"0","（成功）。非零表示错误。",[188,303,304,307],{},[32,305,306],{},"process.on('exit', (code) => {...})","：在进程退出前执行（只能执行同步操作，异步会被忽略）。",[69,309,311],{"className":71,"code":310,"language":73,"meta":74,"style":74},"process.on(\"exit\", code => {\n    console.log(`进程即将退出，退出码：${code}`);\n});\nprocess.exit(1); \u002F\u002F 触发 exit 事件，然后退出\n",[32,312,313,343,373,382],{"__ignoreMap":74},[78,314,315,317,319,322,324,326,328,330,333,337,340],{"class":80,"line":81},[78,316,13],{"class":84},[78,318,89],{"class":88},[78,320,321],{"class":92},"on",[78,323,238],{"class":84},[78,325,146],{"class":138},[78,327,285],{"class":142},[78,329,146],{"class":138},[78,331,332],{"class":88},",",[78,334,336],{"class":335},"s99_P"," code",[78,338,339],{"class":217}," =>",[78,341,342],{"class":88}," {\n",[78,344,345,348,350,352,355,358,361,364,366,369,371],{"class":80,"line":120},[78,346,347],{"class":84},"    console",[78,349,89],{"class":88},[78,351,93],{"class":92},[78,353,238],{"class":354},"skxfh",[78,356,357],{"class":138},"`",[78,359,360],{"class":142},"进程即将退出，退出码：",[78,362,363],{"class":138},"${",[78,365,32],{"class":84},[78,367,368],{"class":138},"}`",[78,370,110],{"class":354},[78,372,247],{"class":88},[78,374,375,378,380],{"class":80,"line":154},[78,376,377],{"class":88},"}",[78,379,110],{"class":84},[78,381,247],{"class":88},[78,383,385,387,389,391,393,396,398,400],{"class":80,"line":384},4,[78,386,13],{"class":84},[78,388,89],{"class":88},[78,390,285],{"class":92},[78,392,238],{"class":84},[78,394,395],{"class":241},"1",[78,397,110],{"class":84},[78,399,113],{"class":88},[78,401,402],{"class":116}," \u002F\u002F 触发 exit 事件，然后退出\n",[57,404,406,407,64],{"id":405},"_4-信号处理processonsig","4. 信号处理（",[32,408,409],{},"process.on('SIG...')",[28,411,412,413,416,417,420,421,424],{},"可以监听 POSIX 信号，如 ",[32,414,415],{},"SIGINT","（Ctrl+C）、",[32,418,419],{},"SIGTERM","、",[32,422,423],{},"SIGUSR1"," 等。",[69,426,428],{"className":71,"code":427,"language":73,"meta":74,"style":74},"process.on(\"SIGINT\", () => {\n    console.log(\"收到 SIGINT，优雅退出\");\n    process.exit(0);\n});\n",[32,429,430,455,476,493],{"__ignoreMap":74},[78,431,432,434,436,438,440,442,444,446,448,451,453],{"class":80,"line":81},[78,433,13],{"class":84},[78,435,89],{"class":88},[78,437,321],{"class":92},[78,439,238],{"class":84},[78,441,146],{"class":138},[78,443,415],{"class":142},[78,445,146],{"class":138},[78,447,332],{"class":88},[78,449,450],{"class":88}," ()",[78,452,339],{"class":217},[78,454,342],{"class":88},[78,456,457,459,461,463,465,467,470,472,474],{"class":80,"line":120},[78,458,347],{"class":84},[78,460,89],{"class":88},[78,462,93],{"class":92},[78,464,238],{"class":354},[78,466,146],{"class":138},[78,468,469],{"class":142},"收到 SIGINT，优雅退出",[78,471,146],{"class":138},[78,473,110],{"class":354},[78,475,247],{"class":88},[78,477,478,481,483,485,487,489,491],{"class":80,"line":154},[78,479,480],{"class":84},"    process",[78,482,89],{"class":88},[78,484,285],{"class":92},[78,486,238],{"class":354},[78,488,300],{"class":241},[78,490,110],{"class":354},[78,492,247],{"class":88},[78,494,495,497,499],{"class":80,"line":384},[78,496,377],{"class":88},[78,498,110],{"class":84},[78,500,247],{"class":88},[57,502,504,505,282,508,64],{"id":503},"_5-当前工作目录processcwd-与-processchdir","5. 当前工作目录（",[32,506,507],{},"process.cwd()",[32,509,510],{},"process.chdir()",[185,512,513,522],{},[188,514,515,517,518,521],{},[32,516,507],{},"：返回当前工作目录（即执行 ",[32,519,520],{},"node"," 命令时的目录）。",[188,523,524,527],{},[32,525,526],{},"process.chdir(path)","：改变工作目录。",[69,529,531],{"className":71,"code":530,"language":73,"meta":74,"style":74},"console.log(process.cwd()); \u002F\u002F \u002Fhome\u002Fuser\u002Fproject\nprocess.chdir(\"\u002Ftmp\");\nconsole.log(process.cwd()); \u002F\u002F \u002Ftmp\n",[32,532,533,556,578],{"__ignoreMap":74},[78,534,535,537,539,541,543,545,548,551,553],{"class":80,"line":81},[78,536,85],{"class":84},[78,538,89],{"class":88},[78,540,93],{"class":92},[78,542,96],{"class":84},[78,544,89],{"class":88},[78,546,547],{"class":92},"cwd",[78,549,550],{"class":84},"())",[78,552,113],{"class":88},[78,554,555],{"class":116}," \u002F\u002F \u002Fhome\u002Fuser\u002Fproject\n",[78,557,558,560,562,565,567,569,572,574,576],{"class":80,"line":120},[78,559,13],{"class":84},[78,561,89],{"class":88},[78,563,564],{"class":92},"chdir",[78,566,238],{"class":84},[78,568,146],{"class":138},[78,570,571],{"class":142},"\u002Ftmp",[78,573,146],{"class":138},[78,575,110],{"class":84},[78,577,247],{"class":88},[78,579,580,582,584,586,588,590,592,594,596],{"class":80,"line":154},[78,581,85],{"class":84},[78,583,89],{"class":88},[78,585,93],{"class":92},[78,587,96],{"class":84},[78,589,89],{"class":88},[78,591,547],{"class":92},[78,593,550],{"class":84},[78,595,113],{"class":88},[78,597,598],{"class":116}," \u002F\u002F \u002Ftmp\n",[57,600,602,603,64],{"id":601},"_6-文件权限掩码processumask","6. 文件权限掩码（",[32,604,605],{},"process.umask()",[28,607,608],{},"设置或返回 Node.js 进程的文件权限掩码，影响新创建文件的权限。不推荐频繁修改。",[69,610,612],{"className":71,"code":611,"language":73,"meta":74,"style":74},"const oldMask = process.umask(0o022);\nconsole.log(oldMask.toString(8));\n",[32,613,614,639],{"__ignoreMap":74},[78,615,616,618,621,623,625,627,630,632,635,637],{"class":80,"line":81},[78,617,218],{"class":217},[78,619,620],{"class":106}," oldMask",[78,622,135],{"class":134},[78,624,160],{"class":84},[78,626,89],{"class":88},[78,628,629],{"class":92},"umask",[78,631,238],{"class":84},[78,633,634],{"class":241},"0o022",[78,636,110],{"class":84},[78,638,247],{"class":88},[78,640,641,643,645,647,650,652,655,657,660,663],{"class":80,"line":120},[78,642,85],{"class":84},[78,644,89],{"class":88},[78,646,93],{"class":92},[78,648,649],{"class":84},"(oldMask",[78,651,89],{"class":88},[78,653,654],{"class":92},"toString",[78,656,238],{"class":84},[78,658,659],{"class":241},"8",[78,661,662],{"class":84},"))",[78,664,247],{"class":88},[57,666,668,669,64],{"id":667},"_7-内存使用processmemoryusage","7. 内存使用（",[32,670,671],{},"process.memoryUsage()",[28,673,674],{},"返回对象，描述 Node.js 进程的内存使用情况（单位：字节）。",[185,676,677,683,689,695],{},[188,678,679,682],{},[32,680,681],{},"rss","：常驻内存大小（Resident Set Size）",[188,684,685,688],{},[32,686,687],{},"heapTotal","：V8 堆内存总分配量",[188,690,691,694],{},[32,692,693],{},"heapUsed","：实际使用的堆内存",[188,696,697,700],{},[32,698,699],{},"external","：C++ 对象占用的内存",[69,702,704],{"className":71,"code":703,"language":73,"meta":74,"style":74},"console.log(process.memoryUsage());\n",[32,705,706],{"__ignoreMap":74},[78,707,708,710,712,714,716,718,721,723],{"class":80,"line":81},[78,709,85],{"class":84},[78,711,89],{"class":88},[78,713,93],{"class":92},[78,715,96],{"class":84},[78,717,89],{"class":88},[78,719,720],{"class":92},"memoryUsage",[78,722,550],{"class":84},[78,724,247],{"class":88},[28,726,727,728,420,731,734],{},"此外还有 ",[32,729,730],{},"process.cpuUsage()",[32,732,733],{},"process.hrtime()"," 等高精度性能测量方法。",[44,736,738,739,741],{"id":737},"二子进程child_process-模块","二、子进程（",[32,740,37],{}," 模块）",[28,743,744,745,420,748,420,751,420,754,757,758,760],{},"Node.js 可以创建子进程执行外部命令或脚本。四种核心方法：",[32,746,747],{},"exec",[32,749,750],{},"execFile",[32,752,753],{},"spawn",[32,755,756],{},"fork","。它们都基于 ",[32,759,753],{},"，但提供了不同层级的封装。",[762,763,764,783],"table",{},[765,766,767],"thead",{},[768,769,770,774,777,780],"tr",{},[771,772,773],"th",{},"方法",[771,775,776],{},"特点",[771,778,779],{},"适用场景",[771,781,782],{},"回调\u002F输出大小",[784,785,786,802,817,840],"tbody",{},[768,787,788,793,796,799],{},[789,790,791],"td",{},[32,792,747],{},[789,794,795],{},"执行 shell 命令，将输出缓冲到回调",[789,797,798],{},"执行简单命令，输出较小",[789,800,801],{},"有最大缓冲限制（默认 1MB）",[768,803,804,808,811,814],{},[789,805,806],{},[32,807,750],{},[789,809,810],{},"直接执行可执行文件，不启动 shell",[789,812,813],{},"执行特定二进制文件，更安全",[789,815,816],{},"同样有缓冲限制",[768,818,819,823,834,837],{},[789,820,821],{},[32,822,753],{},[789,824,825,826,829,830,833],{},"流式输出，返回 ",[32,827,828],{},"stdout","\u002F",[32,831,832],{},"stderr"," 流",[789,835,836],{},"大量输出或实时处理数据",[789,838,839],{},"无缓冲上限",[768,841,842,846,849,852],{},[789,843,844],{},[32,845,756],{},[789,847,848],{},"专门用于派生新的 Node.js 进程，自带通信 IPC",[789,850,851],{},"在子进程中运行 Node.js 模块，需要进程间通信",[789,853,854],{},"基于 IPC 消息传递",[57,856,858,859,282,861],{"id":857},"_1-exec-与-execfile","1. ",[32,860,747],{},[32,862,750],{},[69,864,866],{"className":71,"code":865,"language":73,"meta":74,"style":74},"const { exec, execFile } = require(\"child_process\");\n\n\u002F\u002F exec 使用 shell\nexec(\"ls -la | grep test\", (error, stdout, stderr) => {\n    if (error) console.error(error);\n    console.log(stdout);\n});\n\n\u002F\u002F execFile 直接执行程序，更高效\nexecFile(\"node\", [\"--version\"], (error, stdout) => {\n    console.log(stdout); \u002F\u002F v18.x.x\n});\n",[32,867,868,903,909,914,951,979,996,1005,1010,1016,1060,1080],{"__ignoreMap":74},[78,869,870,872,875,878,880,883,886,888,891,893,895,897,899,901],{"class":80,"line":81},[78,871,218],{"class":217},[78,873,874],{"class":88}," {",[78,876,877],{"class":106}," exec",[78,879,332],{"class":88},[78,881,882],{"class":106}," execFile",[78,884,885],{"class":88}," }",[78,887,135],{"class":134},[78,889,890],{"class":92}," require",[78,892,238],{"class":84},[78,894,146],{"class":138},[78,896,37],{"class":142},[78,898,146],{"class":138},[78,900,110],{"class":84},[78,902,247],{"class":88},[78,904,905],{"class":80,"line":120},[78,906,908],{"emptyLinePlaceholder":907},true,"\n",[78,910,911],{"class":80,"line":154},[78,912,913],{"class":116},"\u002F\u002F exec 使用 shell\n",[78,915,916,918,920,922,925,927,929,932,935,937,940,942,945,947,949],{"class":80,"line":384},[78,917,747],{"class":92},[78,919,238],{"class":84},[78,921,146],{"class":138},[78,923,924],{"class":142},"ls -la | grep test",[78,926,146],{"class":138},[78,928,332],{"class":88},[78,930,931],{"class":88}," (",[78,933,934],{"class":335},"error",[78,936,332],{"class":88},[78,938,939],{"class":335}," stdout",[78,941,332],{"class":88},[78,943,944],{"class":335}," stderr",[78,946,110],{"class":88},[78,948,339],{"class":217},[78,950,342],{"class":88},[78,952,954,958,960,962,965,967,969,971,973,975,977],{"class":80,"line":953},5,[78,955,957],{"class":956},"sVHd0","    if",[78,959,931],{"class":354},[78,961,934],{"class":84},[78,963,964],{"class":354},") ",[78,966,85],{"class":84},[78,968,89],{"class":88},[78,970,934],{"class":92},[78,972,238],{"class":354},[78,974,934],{"class":84},[78,976,110],{"class":354},[78,978,247],{"class":88},[78,980,982,984,986,988,990,992,994],{"class":80,"line":981},6,[78,983,347],{"class":84},[78,985,89],{"class":88},[78,987,93],{"class":92},[78,989,238],{"class":354},[78,991,828],{"class":84},[78,993,110],{"class":354},[78,995,247],{"class":88},[78,997,999,1001,1003],{"class":80,"line":998},7,[78,1000,377],{"class":88},[78,1002,110],{"class":84},[78,1004,247],{"class":88},[78,1006,1008],{"class":80,"line":1007},8,[78,1009,908],{"emptyLinePlaceholder":907},[78,1011,1013],{"class":80,"line":1012},9,[78,1014,1015],{"class":116},"\u002F\u002F execFile 直接执行程序，更高效\n",[78,1017,1019,1021,1023,1025,1027,1029,1031,1034,1036,1039,1041,1044,1046,1048,1050,1052,1054,1056,1058],{"class":80,"line":1018},10,[78,1020,750],{"class":92},[78,1022,238],{"class":84},[78,1024,146],{"class":138},[78,1026,520],{"class":142},[78,1028,146],{"class":138},[78,1030,332],{"class":88},[78,1032,1033],{"class":84}," [",[78,1035,146],{"class":138},[78,1037,1038],{"class":142},"--version",[78,1040,146],{"class":138},[78,1042,1043],{"class":84},"]",[78,1045,332],{"class":88},[78,1047,931],{"class":88},[78,1049,934],{"class":335},[78,1051,332],{"class":88},[78,1053,939],{"class":335},[78,1055,110],{"class":88},[78,1057,339],{"class":217},[78,1059,342],{"class":88},[78,1061,1063,1065,1067,1069,1071,1073,1075,1077],{"class":80,"line":1062},11,[78,1064,347],{"class":84},[78,1066,89],{"class":88},[78,1068,93],{"class":92},[78,1070,238],{"class":354},[78,1072,828],{"class":84},[78,1074,110],{"class":354},[78,1076,113],{"class":88},[78,1078,1079],{"class":116}," \u002F\u002F v18.x.x\n",[78,1081,1083,1085,1087],{"class":80,"line":1082},12,[78,1084,377],{"class":88},[78,1086,110],{"class":84},[78,1088,247],{"class":88},[57,1090,1092,1093,1095],{"id":1091},"_2-spawn流式推荐大输出或实时交互","2. ",[32,1094,753],{},"（流式，推荐大输出或实时交互）",[69,1097,1099],{"className":71,"code":1098,"language":73,"meta":74,"style":74},"const { spawn } = require(\"child_process\");\nconst ls = spawn(\"ls\", [\"-lh\", \"\u002Fusr\"]);\n\nls.stdout.on(\"data\", data => {\n    console.log(`输出：${data}`);\n});\nls.stderr.on(\"data\", data => {\n    console.error(`错误：${data}`);\n});\nls.on(\"close\", code => {\n    console.log(`子进程退出码：${code}`);\n});\n",[32,1100,1101,1128,1173,1177,1207,1232,1240,1268,1293,1301,1326,1351],{"__ignoreMap":74},[78,1102,1103,1105,1107,1110,1112,1114,1116,1118,1120,1122,1124,1126],{"class":80,"line":81},[78,1104,218],{"class":217},[78,1106,874],{"class":88},[78,1108,1109],{"class":106}," spawn",[78,1111,885],{"class":88},[78,1113,135],{"class":134},[78,1115,890],{"class":92},[78,1117,238],{"class":84},[78,1119,146],{"class":138},[78,1121,37],{"class":142},[78,1123,146],{"class":138},[78,1125,110],{"class":84},[78,1127,247],{"class":88},[78,1129,1130,1132,1135,1137,1139,1141,1143,1146,1148,1150,1152,1154,1157,1159,1161,1163,1166,1168,1171],{"class":80,"line":120},[78,1131,218],{"class":217},[78,1133,1134],{"class":106}," ls",[78,1136,135],{"class":134},[78,1138,1109],{"class":92},[78,1140,238],{"class":84},[78,1142,146],{"class":138},[78,1144,1145],{"class":142},"ls",[78,1147,146],{"class":138},[78,1149,332],{"class":88},[78,1151,1033],{"class":84},[78,1153,146],{"class":138},[78,1155,1156],{"class":142},"-lh",[78,1158,146],{"class":138},[78,1160,332],{"class":88},[78,1162,139],{"class":138},[78,1164,1165],{"class":142},"\u002Fusr",[78,1167,146],{"class":138},[78,1169,1170],{"class":84},"])",[78,1172,247],{"class":88},[78,1174,1175],{"class":80,"line":154},[78,1176,908],{"emptyLinePlaceholder":907},[78,1178,1179,1181,1183,1185,1187,1189,1191,1193,1196,1198,1200,1203,1205],{"class":80,"line":384},[78,1180,1145],{"class":84},[78,1182,89],{"class":88},[78,1184,828],{"class":84},[78,1186,89],{"class":88},[78,1188,321],{"class":92},[78,1190,238],{"class":84},[78,1192,146],{"class":138},[78,1194,1195],{"class":142},"data",[78,1197,146],{"class":138},[78,1199,332],{"class":88},[78,1201,1202],{"class":335}," data",[78,1204,339],{"class":217},[78,1206,342],{"class":88},[78,1208,1209,1211,1213,1215,1217,1219,1222,1224,1226,1228,1230],{"class":80,"line":953},[78,1210,347],{"class":84},[78,1212,89],{"class":88},[78,1214,93],{"class":92},[78,1216,238],{"class":354},[78,1218,357],{"class":138},[78,1220,1221],{"class":142},"输出：",[78,1223,363],{"class":138},[78,1225,1195],{"class":84},[78,1227,368],{"class":138},[78,1229,110],{"class":354},[78,1231,247],{"class":88},[78,1233,1234,1236,1238],{"class":80,"line":981},[78,1235,377],{"class":88},[78,1237,110],{"class":84},[78,1239,247],{"class":88},[78,1241,1242,1244,1246,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266],{"class":80,"line":998},[78,1243,1145],{"class":84},[78,1245,89],{"class":88},[78,1247,832],{"class":84},[78,1249,89],{"class":88},[78,1251,321],{"class":92},[78,1253,238],{"class":84},[78,1255,146],{"class":138},[78,1257,1195],{"class":142},[78,1259,146],{"class":138},[78,1261,332],{"class":88},[78,1263,1202],{"class":335},[78,1265,339],{"class":217},[78,1267,342],{"class":88},[78,1269,1270,1272,1274,1276,1278,1280,1283,1285,1287,1289,1291],{"class":80,"line":1007},[78,1271,347],{"class":84},[78,1273,89],{"class":88},[78,1275,934],{"class":92},[78,1277,238],{"class":354},[78,1279,357],{"class":138},[78,1281,1282],{"class":142},"错误：",[78,1284,363],{"class":138},[78,1286,1195],{"class":84},[78,1288,368],{"class":138},[78,1290,110],{"class":354},[78,1292,247],{"class":88},[78,1294,1295,1297,1299],{"class":80,"line":1012},[78,1296,377],{"class":88},[78,1298,110],{"class":84},[78,1300,247],{"class":88},[78,1302,1303,1305,1307,1309,1311,1313,1316,1318,1320,1322,1324],{"class":80,"line":1018},[78,1304,1145],{"class":84},[78,1306,89],{"class":88},[78,1308,321],{"class":92},[78,1310,238],{"class":84},[78,1312,146],{"class":138},[78,1314,1315],{"class":142},"close",[78,1317,146],{"class":138},[78,1319,332],{"class":88},[78,1321,336],{"class":335},[78,1323,339],{"class":217},[78,1325,342],{"class":88},[78,1327,1328,1330,1332,1334,1336,1338,1341,1343,1345,1347,1349],{"class":80,"line":1062},[78,1329,347],{"class":84},[78,1331,89],{"class":88},[78,1333,93],{"class":92},[78,1335,238],{"class":354},[78,1337,357],{"class":138},[78,1339,1340],{"class":142},"子进程退出码：",[78,1342,363],{"class":138},[78,1344,32],{"class":84},[78,1346,368],{"class":138},[78,1348,110],{"class":354},[78,1350,247],{"class":88},[78,1352,1353,1355,1357],{"class":80,"line":1082},[78,1354,377],{"class":88},[78,1356,110],{"class":84},[78,1358,247],{"class":88},[57,1360,1362,1363,1365],{"id":1361},"_3-forknodejs-子进程-ipc","3. ",[32,1364,756],{},"（Node.js 子进程 + IPC）",[28,1367,1368,1369,1372],{},"父进程 ",[32,1370,1371],{},"parent.js","：",[69,1374,1376],{"className":71,"code":1375,"language":73,"meta":74,"style":74},"const { fork } = require(\"child_process\");\nconst child = fork(\".\u002Fchild.js\");\n\nchild.on(\"message\", msg => {\n    console.log(\"收到子进程消息：\", msg);\n});\nchild.send({ hello: \"parent\" });\n",[32,1377,1378,1405,1429,1433,1460,1485,1493],{"__ignoreMap":74},[78,1379,1380,1382,1384,1387,1389,1391,1393,1395,1397,1399,1401,1403],{"class":80,"line":81},[78,1381,218],{"class":217},[78,1383,874],{"class":88},[78,1385,1386],{"class":106}," fork",[78,1388,885],{"class":88},[78,1390,135],{"class":134},[78,1392,890],{"class":92},[78,1394,238],{"class":84},[78,1396,146],{"class":138},[78,1398,37],{"class":142},[78,1400,146],{"class":138},[78,1402,110],{"class":84},[78,1404,247],{"class":88},[78,1406,1407,1409,1412,1414,1416,1418,1420,1423,1425,1427],{"class":80,"line":120},[78,1408,218],{"class":217},[78,1410,1411],{"class":106}," child",[78,1413,135],{"class":134},[78,1415,1386],{"class":92},[78,1417,238],{"class":84},[78,1419,146],{"class":138},[78,1421,1422],{"class":142},".\u002Fchild.js",[78,1424,146],{"class":138},[78,1426,110],{"class":84},[78,1428,247],{"class":88},[78,1430,1431],{"class":80,"line":154},[78,1432,908],{"emptyLinePlaceholder":907},[78,1434,1435,1438,1440,1442,1444,1446,1449,1451,1453,1456,1458],{"class":80,"line":384},[78,1436,1437],{"class":84},"child",[78,1439,89],{"class":88},[78,1441,321],{"class":92},[78,1443,238],{"class":84},[78,1445,146],{"class":138},[78,1447,1448],{"class":142},"message",[78,1450,146],{"class":138},[78,1452,332],{"class":88},[78,1454,1455],{"class":335}," msg",[78,1457,339],{"class":217},[78,1459,342],{"class":88},[78,1461,1462,1464,1466,1468,1470,1472,1475,1477,1479,1481,1483],{"class":80,"line":953},[78,1463,347],{"class":84},[78,1465,89],{"class":88},[78,1467,93],{"class":92},[78,1469,238],{"class":354},[78,1471,146],{"class":138},[78,1473,1474],{"class":142},"收到子进程消息：",[78,1476,146],{"class":138},[78,1478,332],{"class":88},[78,1480,1455],{"class":84},[78,1482,110],{"class":354},[78,1484,247],{"class":88},[78,1486,1487,1489,1491],{"class":80,"line":981},[78,1488,377],{"class":88},[78,1490,110],{"class":84},[78,1492,247],{"class":88},[78,1494,1495,1497,1499,1502,1504,1507,1510,1513,1515,1518,1520,1522,1524],{"class":80,"line":998},[78,1496,1437],{"class":84},[78,1498,89],{"class":88},[78,1500,1501],{"class":92},"send",[78,1503,238],{"class":84},[78,1505,1506],{"class":88},"{",[78,1508,1509],{"class":354}," hello",[78,1511,1512],{"class":88},":",[78,1514,139],{"class":138},[78,1516,1517],{"class":142},"parent",[78,1519,146],{"class":138},[78,1521,885],{"class":88},[78,1523,110],{"class":84},[78,1525,247],{"class":88},[28,1527,1528,1529,1372],{},"子进程 ",[32,1530,1531],{},"child.js",[69,1533,1535],{"className":71,"code":1534,"language":73,"meta":74,"style":74},"process.on(\"message\", msg => {\n    console.log(\"父进程消息：\", msg);\n    process.send({ reply: \"from child\" });\n});\n",[32,1536,1537,1561,1586,1616],{"__ignoreMap":74},[78,1538,1539,1541,1543,1545,1547,1549,1551,1553,1555,1557,1559],{"class":80,"line":81},[78,1540,13],{"class":84},[78,1542,89],{"class":88},[78,1544,321],{"class":92},[78,1546,238],{"class":84},[78,1548,146],{"class":138},[78,1550,1448],{"class":142},[78,1552,146],{"class":138},[78,1554,332],{"class":88},[78,1556,1455],{"class":335},[78,1558,339],{"class":217},[78,1560,342],{"class":88},[78,1562,1563,1565,1567,1569,1571,1573,1576,1578,1580,1582,1584],{"class":80,"line":120},[78,1564,347],{"class":84},[78,1566,89],{"class":88},[78,1568,93],{"class":92},[78,1570,238],{"class":354},[78,1572,146],{"class":138},[78,1574,1575],{"class":142},"父进程消息：",[78,1577,146],{"class":138},[78,1579,332],{"class":88},[78,1581,1455],{"class":84},[78,1583,110],{"class":354},[78,1585,247],{"class":88},[78,1587,1588,1590,1592,1594,1596,1598,1601,1603,1605,1608,1610,1612,1614],{"class":80,"line":154},[78,1589,480],{"class":84},[78,1591,89],{"class":88},[78,1593,1501],{"class":92},[78,1595,238],{"class":354},[78,1597,1506],{"class":88},[78,1599,1600],{"class":354}," reply",[78,1602,1512],{"class":88},[78,1604,139],{"class":138},[78,1606,1607],{"class":142},"from child",[78,1609,146],{"class":138},[78,1611,885],{"class":88},[78,1613,110],{"class":354},[78,1615,247],{"class":88},[78,1617,1618,1620,1622],{"class":80,"line":384},[78,1619,377],{"class":88},[78,1621,110],{"class":84},[78,1623,247],{"class":88},[28,1625,1626,1628,1629,1632],{},[32,1627,756],{}," 的第二个参数可以指定 ",[32,1630,1631],{},"silent: true"," 来屏蔽子进程的标准输出。",[57,1634,1636],{"id":1635},"_4-父子进程通信ipc","4. 父子进程通信（IPC）",[185,1638,1639,1653],{},[188,1640,1641,1642,1644,1645,1648,1649,1652],{},"使用 ",[32,1643,756],{}," 时自动建立 IPC 通道，可调用 ",[32,1646,1647],{},"child.send(message)"," 和监听 ",[32,1650,1651],{},"'message'"," 事件。",[188,1654,1655,1656,1658,1659,1662,1663,1666,1667,1670],{},"对于 ",[32,1657,753],{},"，可以通过 ",[32,1660,1661],{},"stdio: ['ipc']"," 选项启用 IPC，然后使用 ",[32,1664,1665],{},".send"," 和 ",[32,1668,1669],{},"on('message')"," 通信。",[57,1672,1674],{"id":1673},"_5-执行外部命令如-python-脚本","5. 执行外部命令（如 Python 脚本）",[69,1676,1678],{"className":71,"code":1677,"language":73,"meta":74,"style":74},"const { spawn } = require(\"child_process\");\nconst python = spawn(\"python\", [\"script.py\", \"arg1\"]);\n\npython.stdout.on(\"data\", data => console.log(data.toString()));\npython.stderr.on(\"data\", data => console.error(data.toString()));\n",[32,1679,1680,1706,1750,1754,1799],{"__ignoreMap":74},[78,1681,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700,1702,1704],{"class":80,"line":81},[78,1683,218],{"class":217},[78,1685,874],{"class":88},[78,1687,1109],{"class":106},[78,1689,885],{"class":88},[78,1691,135],{"class":134},[78,1693,890],{"class":92},[78,1695,238],{"class":84},[78,1697,146],{"class":138},[78,1699,37],{"class":142},[78,1701,146],{"class":138},[78,1703,110],{"class":84},[78,1705,247],{"class":88},[78,1707,1708,1710,1713,1715,1717,1719,1721,1724,1726,1728,1730,1732,1735,1737,1739,1741,1744,1746,1748],{"class":80,"line":120},[78,1709,218],{"class":217},[78,1711,1712],{"class":106}," python",[78,1714,135],{"class":134},[78,1716,1109],{"class":92},[78,1718,238],{"class":84},[78,1720,146],{"class":138},[78,1722,1723],{"class":142},"python",[78,1725,146],{"class":138},[78,1727,332],{"class":88},[78,1729,1033],{"class":84},[78,1731,146],{"class":138},[78,1733,1734],{"class":142},"script.py",[78,1736,146],{"class":138},[78,1738,332],{"class":88},[78,1740,139],{"class":138},[78,1742,1743],{"class":142},"arg1",[78,1745,146],{"class":138},[78,1747,1170],{"class":84},[78,1749,247],{"class":88},[78,1751,1752],{"class":80,"line":154},[78,1753,908],{"emptyLinePlaceholder":907},[78,1755,1756,1758,1760,1762,1764,1766,1768,1770,1772,1774,1776,1778,1780,1783,1785,1787,1790,1792,1794,1797],{"class":80,"line":384},[78,1757,1723],{"class":84},[78,1759,89],{"class":88},[78,1761,828],{"class":84},[78,1763,89],{"class":88},[78,1765,321],{"class":92},[78,1767,238],{"class":84},[78,1769,146],{"class":138},[78,1771,1195],{"class":142},[78,1773,146],{"class":138},[78,1775,332],{"class":88},[78,1777,1202],{"class":335},[78,1779,339],{"class":217},[78,1781,1782],{"class":84}," console",[78,1784,89],{"class":88},[78,1786,93],{"class":92},[78,1788,1789],{"class":84},"(data",[78,1791,89],{"class":88},[78,1793,654],{"class":92},[78,1795,1796],{"class":84},"()))",[78,1798,247],{"class":88},[78,1800,1801,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839],{"class":80,"line":953},[78,1802,1723],{"class":84},[78,1804,89],{"class":88},[78,1806,832],{"class":84},[78,1808,89],{"class":88},[78,1810,321],{"class":92},[78,1812,238],{"class":84},[78,1814,146],{"class":138},[78,1816,1195],{"class":142},[78,1818,146],{"class":138},[78,1820,332],{"class":88},[78,1822,1202],{"class":335},[78,1824,339],{"class":217},[78,1826,1782],{"class":84},[78,1828,89],{"class":88},[78,1830,934],{"class":92},[78,1832,1789],{"class":84},[78,1834,89],{"class":88},[78,1836,654],{"class":92},[78,1838,1796],{"class":84},[78,1840,247],{"class":88},[57,1842,1844],{"id":1843},"_6-子进程的其他控制","6. 子进程的其他控制",[185,1846,1847,1853,1859],{},[188,1848,1849,1852],{},[32,1850,1851],{},"child.kill([signal])","：发送信号终止子进程。",[188,1854,1855,1858],{},[32,1856,1857],{},"child.pid","：获取子进程 PID。",[188,1860,1861,1862,1865],{},"通过 ",[32,1863,1864],{},"options.detached: true"," 使子进程独立于父进程运行。",[44,1867,1869,1870,64],{"id":1868},"三工作线程worker_threads","三、工作线程（",[32,1871,41],{},[28,1873,1874],{},"工作线程用于执行 CPU 密集型 JavaScript 任务，不阻塞主线程。它们共享同一进程的 V8 实例，但运行在独立的事件循环中。",[57,1876,1878],{"id":1877},"_1-基本用法","1. 基本用法",[28,1880,1881,1882,1372],{},"主线程 ",[32,1883,1884],{},"main.js",[69,1886,1888],{"className":71,"code":1887,"language":73,"meta":74,"style":74},"const { Worker } = require(\"worker_threads\");\n\nconst worker = new Worker(\".\u002Fworker.js\", { workerData: { start: 1 } });\n\nworker.on(\"message\", result => console.log(\"结果：\", result));\nworker.on(\"error\", err => console.error(err));\nworker.on(\"exit\", code => console.log(`Worker 退出码 ${code}`));\n\n\u002F\u002F 向 worker 发送消息\nworker.postMessage({ cmd: \"compute\" });\n",[32,1889,1890,1917,1921,1971,1975,2021,2055,2100,2104,2109],{"__ignoreMap":74},[78,1891,1892,1894,1896,1899,1901,1903,1905,1907,1909,1911,1913,1915],{"class":80,"line":81},[78,1893,218],{"class":217},[78,1895,874],{"class":88},[78,1897,1898],{"class":106}," Worker",[78,1900,885],{"class":88},[78,1902,135],{"class":134},[78,1904,890],{"class":92},[78,1906,238],{"class":84},[78,1908,146],{"class":138},[78,1910,41],{"class":142},[78,1912,146],{"class":138},[78,1914,110],{"class":84},[78,1916,247],{"class":88},[78,1918,1919],{"class":80,"line":120},[78,1920,908],{"emptyLinePlaceholder":907},[78,1922,1923,1925,1928,1930,1933,1935,1937,1939,1942,1944,1946,1948,1951,1953,1955,1958,1960,1963,1965,1967,1969],{"class":80,"line":154},[78,1924,218],{"class":217},[78,1926,1927],{"class":106}," worker",[78,1929,135],{"class":134},[78,1931,1932],{"class":134}," new",[78,1934,1898],{"class":92},[78,1936,238],{"class":84},[78,1938,146],{"class":138},[78,1940,1941],{"class":142},".\u002Fworker.js",[78,1943,146],{"class":138},[78,1945,332],{"class":88},[78,1947,874],{"class":88},[78,1949,1950],{"class":354}," workerData",[78,1952,1512],{"class":88},[78,1954,874],{"class":88},[78,1956,1957],{"class":354}," start",[78,1959,1512],{"class":88},[78,1961,1962],{"class":241}," 1",[78,1964,885],{"class":88},[78,1966,885],{"class":88},[78,1968,110],{"class":84},[78,1970,247],{"class":88},[78,1972,1973],{"class":80,"line":384},[78,1974,908],{"emptyLinePlaceholder":907},[78,1976,1977,1980,1982,1984,1986,1988,1990,1992,1994,1997,1999,2001,2003,2005,2007,2009,2012,2014,2016,2019],{"class":80,"line":953},[78,1978,1979],{"class":84},"worker",[78,1981,89],{"class":88},[78,1983,321],{"class":92},[78,1985,238],{"class":84},[78,1987,146],{"class":138},[78,1989,1448],{"class":142},[78,1991,146],{"class":138},[78,1993,332],{"class":88},[78,1995,1996],{"class":335}," result",[78,1998,339],{"class":217},[78,2000,1782],{"class":84},[78,2002,89],{"class":88},[78,2004,93],{"class":92},[78,2006,238],{"class":84},[78,2008,146],{"class":138},[78,2010,2011],{"class":142},"结果：",[78,2013,146],{"class":138},[78,2015,332],{"class":88},[78,2017,2018],{"class":84}," result))",[78,2020,247],{"class":88},[78,2022,2023,2025,2027,2029,2031,2033,2035,2037,2039,2042,2044,2046,2048,2050,2053],{"class":80,"line":981},[78,2024,1979],{"class":84},[78,2026,89],{"class":88},[78,2028,321],{"class":92},[78,2030,238],{"class":84},[78,2032,146],{"class":138},[78,2034,934],{"class":142},[78,2036,146],{"class":138},[78,2038,332],{"class":88},[78,2040,2041],{"class":335}," err",[78,2043,339],{"class":217},[78,2045,1782],{"class":84},[78,2047,89],{"class":88},[78,2049,934],{"class":92},[78,2051,2052],{"class":84},"(err))",[78,2054,247],{"class":88},[78,2056,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079,2081,2083,2085,2087,2090,2092,2094,2096,2098],{"class":80,"line":998},[78,2058,1979],{"class":84},[78,2060,89],{"class":88},[78,2062,321],{"class":92},[78,2064,238],{"class":84},[78,2066,146],{"class":138},[78,2068,285],{"class":142},[78,2070,146],{"class":138},[78,2072,332],{"class":88},[78,2074,336],{"class":335},[78,2076,339],{"class":217},[78,2078,1782],{"class":84},[78,2080,89],{"class":88},[78,2082,93],{"class":92},[78,2084,238],{"class":84},[78,2086,357],{"class":138},[78,2088,2089],{"class":142},"Worker 退出码 ",[78,2091,363],{"class":138},[78,2093,32],{"class":84},[78,2095,368],{"class":138},[78,2097,662],{"class":84},[78,2099,247],{"class":88},[78,2101,2102],{"class":80,"line":1007},[78,2103,908],{"emptyLinePlaceholder":907},[78,2105,2106],{"class":80,"line":1012},[78,2107,2108],{"class":116},"\u002F\u002F 向 worker 发送消息\n",[78,2110,2111,2113,2115,2118,2120,2122,2125,2127,2129,2132,2134,2136,2138],{"class":80,"line":1018},[78,2112,1979],{"class":84},[78,2114,89],{"class":88},[78,2116,2117],{"class":92},"postMessage",[78,2119,238],{"class":84},[78,2121,1506],{"class":88},[78,2123,2124],{"class":354}," cmd",[78,2126,1512],{"class":88},[78,2128,139],{"class":138},[78,2130,2131],{"class":142},"compute",[78,2133,146],{"class":138},[78,2135,885],{"class":88},[78,2137,110],{"class":84},[78,2139,247],{"class":88},[28,2141,2142,2143,1372],{},"工作线程 ",[32,2144,2145],{},"worker.js",[69,2147,2149],{"className":71,"code":2148,"language":73,"meta":74,"style":74},"const { parentPort, workerData } = require(\"worker_threads\");\n\n\u002F\u002F 接收主线程消息\nparentPort.on(\"message\", msg => {\n    if (msg.cmd === \"compute\") {\n        let result = heavyComputation(workerData.start);\n        parentPort.postMessage(result);\n    }\n});\n\nfunction heavyComputation(start) {\n    \u002F\u002F 模拟 CPU 密集型任务\n    let sum = 0;\n    for (let i = 0; i \u003C 1e8; i++) sum += i;\n    return sum;\n}\n",[32,2150,2151,2182,2186,2191,2216,2244,2270,2288,2293,2301,2305,2320,2325,2341,2388,2398],{"__ignoreMap":74},[78,2152,2153,2155,2157,2160,2162,2164,2166,2168,2170,2172,2174,2176,2178,2180],{"class":80,"line":81},[78,2154,218],{"class":217},[78,2156,874],{"class":88},[78,2158,2159],{"class":106}," parentPort",[78,2161,332],{"class":88},[78,2163,1950],{"class":106},[78,2165,885],{"class":88},[78,2167,135],{"class":134},[78,2169,890],{"class":92},[78,2171,238],{"class":84},[78,2173,146],{"class":138},[78,2175,41],{"class":142},[78,2177,146],{"class":138},[78,2179,110],{"class":84},[78,2181,247],{"class":88},[78,2183,2184],{"class":80,"line":120},[78,2185,908],{"emptyLinePlaceholder":907},[78,2187,2188],{"class":80,"line":154},[78,2189,2190],{"class":116},"\u002F\u002F 接收主线程消息\n",[78,2192,2193,2196,2198,2200,2202,2204,2206,2208,2210,2212,2214],{"class":80,"line":384},[78,2194,2195],{"class":84},"parentPort",[78,2197,89],{"class":88},[78,2199,321],{"class":92},[78,2201,238],{"class":84},[78,2203,146],{"class":138},[78,2205,1448],{"class":142},[78,2207,146],{"class":138},[78,2209,332],{"class":88},[78,2211,1455],{"class":335},[78,2213,339],{"class":217},[78,2215,342],{"class":88},[78,2217,2218,2220,2222,2225,2227,2230,2233,2235,2237,2239,2241],{"class":80,"line":953},[78,2219,957],{"class":956},[78,2221,931],{"class":354},[78,2223,2224],{"class":84},"msg",[78,2226,89],{"class":88},[78,2228,2229],{"class":84},"cmd",[78,2231,2232],{"class":134}," ===",[78,2234,139],{"class":138},[78,2236,2131],{"class":142},[78,2238,146],{"class":138},[78,2240,964],{"class":354},[78,2242,2243],{"class":88},"{\n",[78,2245,2246,2249,2251,2253,2256,2258,2261,2263,2266,2268],{"class":80,"line":981},[78,2247,2248],{"class":217},"        let",[78,2250,1996],{"class":84},[78,2252,135],{"class":134},[78,2254,2255],{"class":92}," heavyComputation",[78,2257,238],{"class":354},[78,2259,2260],{"class":84},"workerData",[78,2262,89],{"class":88},[78,2264,2265],{"class":84},"start",[78,2267,110],{"class":354},[78,2269,247],{"class":88},[78,2271,2272,2275,2277,2279,2281,2284,2286],{"class":80,"line":998},[78,2273,2274],{"class":84},"        parentPort",[78,2276,89],{"class":88},[78,2278,2117],{"class":92},[78,2280,238],{"class":354},[78,2282,2283],{"class":84},"result",[78,2285,110],{"class":354},[78,2287,247],{"class":88},[78,2289,2290],{"class":80,"line":1007},[78,2291,2292],{"class":88},"    }\n",[78,2294,2295,2297,2299],{"class":80,"line":1012},[78,2296,377],{"class":88},[78,2298,110],{"class":84},[78,2300,247],{"class":88},[78,2302,2303],{"class":80,"line":1018},[78,2304,908],{"emptyLinePlaceholder":907},[78,2306,2307,2310,2312,2314,2316,2318],{"class":80,"line":1062},[78,2308,2309],{"class":217},"function",[78,2311,2255],{"class":92},[78,2313,238],{"class":88},[78,2315,2265],{"class":335},[78,2317,110],{"class":88},[78,2319,342],{"class":88},[78,2321,2322],{"class":80,"line":1082},[78,2323,2324],{"class":116},"    \u002F\u002F 模拟 CPU 密集型任务\n",[78,2326,2328,2331,2334,2336,2339],{"class":80,"line":2327},13,[78,2329,2330],{"class":217},"    let",[78,2332,2333],{"class":84}," sum",[78,2335,135],{"class":134},[78,2337,2338],{"class":241}," 0",[78,2340,247],{"class":88},[78,2342,2344,2347,2349,2352,2355,2357,2359,2361,2363,2366,2369,2371,2373,2376,2378,2381,2384,2386],{"class":80,"line":2343},14,[78,2345,2346],{"class":956},"    for",[78,2348,931],{"class":354},[78,2350,2351],{"class":217},"let",[78,2353,2354],{"class":84}," i",[78,2356,135],{"class":134},[78,2358,2338],{"class":241},[78,2360,113],{"class":88},[78,2362,2354],{"class":84},[78,2364,2365],{"class":134}," \u003C",[78,2367,2368],{"class":241}," 1e8",[78,2370,113],{"class":88},[78,2372,2354],{"class":84},[78,2374,2375],{"class":134},"++",[78,2377,964],{"class":354},[78,2379,2380],{"class":84},"sum",[78,2382,2383],{"class":134}," +=",[78,2385,2354],{"class":84},[78,2387,247],{"class":88},[78,2389,2391,2394,2396],{"class":80,"line":2390},15,[78,2392,2393],{"class":956},"    return",[78,2395,2333],{"class":84},[78,2397,247],{"class":88},[78,2399,2401],{"class":80,"line":2400},16,[78,2402,2403],{"class":88},"}\n",[57,2405,2407,2408,64],{"id":2406},"_2-共享内存sharedarraybuffer","2. 共享内存（",[32,2409,2410],{},"SharedArrayBuffer",[28,2412,2413,2415,2416,2418,2419,2422],{},[32,2414,41],{}," 支持使用 ",[32,2417,2410],{}," 在主线程和工作线程之间共享内存，配合 ",[32,2420,2421],{},"Atomics"," 实现同步。",[69,2424,2426],{"className":71,"code":2425,"language":73,"meta":74,"style":74},"\u002F\u002F 主线程\nconst { Worker } = require(\"worker_threads\");\nconst sharedBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2);\nconst sharedArray = new Int32Array(sharedBuffer);\nsharedArray[0] = 0;\n\nconst worker = new Worker(\".\u002Fworker.js\", { workerData: sharedBuffer });\nworker.on(\"message\", () => {\n    console.log(\"主线程读取 sharedArray[0] =\", sharedArray[0]); \u002F\u002F 1\n});\n\n\u002F\u002F worker.js\nconst { parentPort, workerData } = require(\"worker_threads\");\nconst sharedArray = new Int32Array(workerData);\nsharedArray[0] = 1;\nparentPort.postMessage(\"done\");\n",[32,2427,2428,2433,2459,2491,2510,2527,2531,2568,2592,2625,2633,2637,2642,2672,2689,2703],{"__ignoreMap":74},[78,2429,2430],{"class":80,"line":81},[78,2431,2432],{"class":116},"\u002F\u002F 主线程\n",[78,2434,2435,2437,2439,2441,2443,2445,2447,2449,2451,2453,2455,2457],{"class":80,"line":120},[78,2436,218],{"class":217},[78,2438,874],{"class":88},[78,2440,1898],{"class":106},[78,2442,885],{"class":88},[78,2444,135],{"class":134},[78,2446,890],{"class":92},[78,2448,238],{"class":84},[78,2450,146],{"class":138},[78,2452,41],{"class":142},[78,2454,146],{"class":138},[78,2456,110],{"class":84},[78,2458,247],{"class":88},[78,2460,2461,2463,2466,2468,2470,2473,2476,2478,2481,2484,2487,2489],{"class":80,"line":154},[78,2462,218],{"class":217},[78,2464,2465],{"class":106}," sharedBuffer",[78,2467,135],{"class":134},[78,2469,1932],{"class":134},[78,2471,2472],{"class":92}," SharedArrayBuffer",[78,2474,2475],{"class":84},"(Int32Array",[78,2477,89],{"class":88},[78,2479,2480],{"class":106},"BYTES_PER_ELEMENT",[78,2482,2483],{"class":134}," *",[78,2485,2486],{"class":241}," 2",[78,2488,110],{"class":84},[78,2490,247],{"class":88},[78,2492,2493,2495,2498,2500,2502,2505,2508],{"class":80,"line":384},[78,2494,218],{"class":217},[78,2496,2497],{"class":106}," sharedArray",[78,2499,135],{"class":134},[78,2501,1932],{"class":134},[78,2503,2504],{"class":92}," Int32Array",[78,2506,2507],{"class":84},"(sharedBuffer)",[78,2509,247],{"class":88},[78,2511,2512,2515,2517,2520,2523,2525],{"class":80,"line":953},[78,2513,2514],{"class":84},"sharedArray[",[78,2516,300],{"class":241},[78,2518,2519],{"class":84},"] ",[78,2521,2522],{"class":134},"=",[78,2524,2338],{"class":241},[78,2526,247],{"class":88},[78,2528,2529],{"class":80,"line":981},[78,2530,908],{"emptyLinePlaceholder":907},[78,2532,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551,2553,2555,2557,2559,2562,2564,2566],{"class":80,"line":998},[78,2534,218],{"class":217},[78,2536,1927],{"class":106},[78,2538,135],{"class":134},[78,2540,1932],{"class":134},[78,2542,1898],{"class":92},[78,2544,238],{"class":84},[78,2546,146],{"class":138},[78,2548,1941],{"class":142},[78,2550,146],{"class":138},[78,2552,332],{"class":88},[78,2554,874],{"class":88},[78,2556,1950],{"class":354},[78,2558,1512],{"class":88},[78,2560,2561],{"class":84}," sharedBuffer ",[78,2563,377],{"class":88},[78,2565,110],{"class":84},[78,2567,247],{"class":88},[78,2569,2570,2572,2574,2576,2578,2580,2582,2584,2586,2588,2590],{"class":80,"line":1007},[78,2571,1979],{"class":84},[78,2573,89],{"class":88},[78,2575,321],{"class":92},[78,2577,238],{"class":84},[78,2579,146],{"class":138},[78,2581,1448],{"class":142},[78,2583,146],{"class":138},[78,2585,332],{"class":88},[78,2587,450],{"class":88},[78,2589,339],{"class":217},[78,2591,342],{"class":88},[78,2593,2594,2596,2598,2600,2602,2604,2607,2609,2611,2613,2616,2618,2620,2622],{"class":80,"line":1012},[78,2595,347],{"class":84},[78,2597,89],{"class":88},[78,2599,93],{"class":92},[78,2601,238],{"class":354},[78,2603,146],{"class":138},[78,2605,2606],{"class":142},"主线程读取 sharedArray[0] =",[78,2608,146],{"class":138},[78,2610,332],{"class":88},[78,2612,2497],{"class":84},[78,2614,2615],{"class":354},"[",[78,2617,300],{"class":241},[78,2619,1170],{"class":354},[78,2621,113],{"class":88},[78,2623,2624],{"class":116}," \u002F\u002F 1\n",[78,2626,2627,2629,2631],{"class":80,"line":1018},[78,2628,377],{"class":88},[78,2630,110],{"class":84},[78,2632,247],{"class":88},[78,2634,2635],{"class":80,"line":1062},[78,2636,908],{"emptyLinePlaceholder":907},[78,2638,2639],{"class":80,"line":1082},[78,2640,2641],{"class":116},"\u002F\u002F worker.js\n",[78,2643,2644,2646,2648,2650,2652,2654,2656,2658,2660,2662,2664,2666,2668,2670],{"class":80,"line":2327},[78,2645,218],{"class":217},[78,2647,874],{"class":88},[78,2649,2159],{"class":106},[78,2651,332],{"class":88},[78,2653,1950],{"class":106},[78,2655,885],{"class":88},[78,2657,135],{"class":134},[78,2659,890],{"class":92},[78,2661,238],{"class":84},[78,2663,146],{"class":138},[78,2665,41],{"class":142},[78,2667,146],{"class":138},[78,2669,110],{"class":84},[78,2671,247],{"class":88},[78,2673,2674,2676,2678,2680,2682,2684,2687],{"class":80,"line":2343},[78,2675,218],{"class":217},[78,2677,2497],{"class":106},[78,2679,135],{"class":134},[78,2681,1932],{"class":134},[78,2683,2504],{"class":92},[78,2685,2686],{"class":84},"(workerData)",[78,2688,247],{"class":88},[78,2690,2691,2693,2695,2697,2699,2701],{"class":80,"line":2390},[78,2692,2514],{"class":84},[78,2694,300],{"class":241},[78,2696,2519],{"class":84},[78,2698,2522],{"class":134},[78,2700,1962],{"class":241},[78,2702,247],{"class":88},[78,2704,2705,2707,2709,2711,2713,2715,2718,2720,2722],{"class":80,"line":2400},[78,2706,2195],{"class":84},[78,2708,89],{"class":88},[78,2710,2117],{"class":92},[78,2712,238],{"class":84},[78,2714,146],{"class":138},[78,2716,2717],{"class":142},"done",[78,2719,146],{"class":138},[78,2721,110],{"class":84},[78,2723,247],{"class":88},[57,2725,2727,2728,2730],{"id":2726},"_3-与-child_process-的对比","3. 与 ",[32,2729,37],{}," 的对比",[762,2732,2733,2748],{},[765,2734,2735],{},[768,2736,2737,2740,2744],{},[771,2738,2739],{},"特性",[771,2741,2742],{},[32,2743,37],{},[771,2745,2746],{},[32,2747,41],{},[784,2749,2750,2764,2777,2790,2803,2816],{},[768,2751,2752,2758,2761],{},[789,2753,2754],{},[2755,2756,2757],"strong",{},"进程\u002F线程",[789,2759,2760],{},"独立进程",[789,2762,2763],{},"同一进程内的线程",[768,2765,2766,2771,2774],{},[789,2767,2768],{},[2755,2769,2770],{},"资源开销",[789,2772,2773],{},"较大（独立内存、进程等）",[789,2775,2776],{},"较小（共享 V8 实例）",[768,2778,2779,2784,2787],{},[789,2780,2781],{},[2755,2782,2783],{},"适用任务",[789,2785,2786],{},"I\u002FO 密集、执行外部命令",[789,2788,2789],{},"CPU 密集计算",[768,2791,2792,2797,2800],{},[789,2793,2794],{},[2755,2795,2796],{},"通信方式",[789,2798,2799],{},"IPC 或 stdio",[789,2801,2802],{},"消息传递（更高效）",[768,2804,2805,2810,2813],{},[789,2806,2807],{},[2755,2808,2809],{},"全局状态隔离",[789,2811,2812],{},"完全隔离，无共享",[789,2814,2815],{},"可共享内存，但默认不共享全局变量",[768,2817,2818,2823,2826],{},[789,2819,2820],{},[2755,2821,2822],{},"使用场景",[789,2824,2825],{},"运行外部脚本、多进程模型",[789,2827,2828],{},"密集计算、并行处理",[44,2830,2831],{"id":2831},"总结",[185,2833,2834,2841,2859],{},[188,2835,2836,2840],{},[2755,2837,2838],{},[32,2839,13],{}," 对象提供了进程级控制：环境变量、参数、退出、信号、工作目录、内存监控等。",[188,2842,2843,2847,2848,829,2850,2852,2853,2855,2856,2858],{},[2755,2844,2845],{},[32,2846,37],{}," 模块用于创建子进程，四种方法各有侧重：",[32,2849,747],{},[32,2851,750],{}," 适合简单命令且输出少；",[32,2854,753],{}," 适合流式输出；",[32,2857,756],{}," 专用于 Node.js 模块通信。",[188,2860,2861,2865],{},[2755,2862,2863],{},[32,2864,41],{}," 解决 CPU 密集型任务阻塞主线程的问题，支持共享内存，与子进程相比更轻量。",[23,2867,2868],{"id":2868},"推荐参考资料",[185,2870,2871,2891,2897],{},[188,2872,2873,2874,420,2881,420,2886],{},"Node.js 官方文档：",[2875,2876,2880],"a",{"href":2877,"rel":2878},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fprocess.html",[2879],"nofollow","Process",[2875,2882,2885],{"href":2883,"rel":2884},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fchild_process.html",[2879],"Child Process",[2875,2887,2890],{"href":2888,"rel":2889},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fworker_threads.html",[2879],"Worker Threads",[188,2892,2893,2894,2896],{},"深入理解：",[32,2895,37],{}," 四种方法的区别与源码分析",[188,2898,2899],{},"实践：使用 worker_threads 优化计算性能",[28,2901,2902],{},"掌握这些 API，可以构建稳定、高效的多进程\u002F多线程 Node.js 应用。",[2904,2905,2906],"style",{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}",{"title":74,"searchDepth":120,"depth":120,"links":2908},[2909,2918],{"id":25,"depth":120,"text":26,"children":2910},[2911,2913,2915,2917],{"id":46,"depth":154,"text":2912},"一、process 对象",{"id":737,"depth":154,"text":2914},"二、子进程（child_process 模块）",{"id":1868,"depth":154,"text":2916},"三、工作线程（worker_threads）",{"id":2831,"depth":154,"text":2831},{"id":2868,"depth":120,"text":2868},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Fprocess","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Fprocess.md","md",{"items":2924},[2925,2929,2933,2937,2941,2945],{"path":2926,"title":2927,"description":2928,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs","文件系统","Node.js 的 fs 模块提供了与文件系统交互的 API，几乎涵盖了所有标准文件操作。它支持三种风格的 API：同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。",{"path":2930,"title":2931,"description":2932,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fbuffer","缓冲区","Buffer 是 Node.js 全局对象，用于处理二进制数据流（如文件、网络数据）。在 ES6 引入 TypedArray 之前，Buffer 是 Node.js 处理二进制的主要方式；现在 Buffer 实现了 Uint8Arra…",{"path":2934,"title":2935,"description":2936,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath","路径处理","path 模块提供了用于处理和转换文件路径的实用工具。它是 Node.js 核心模块，无需安装即可直接使用。由于不同操作系统（Windows、Linux、macOS）的路径分隔符不同（Windows 使用反斜杠 \\，POSIX 使用正…",{"path":2938,"title":2939,"description":2940,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fhttp","网络编程","Node.js 提供了丰富的内置模块，用于构建网络应用。下面从 HTTP\u002FHTTPS、WebSocket、TCP\u002FUDP 以及 DNS 解析四个方面进行深入介绍。",{"path":2942,"title":2943,"description":2944,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fstream","流","流是 Node.js 中处理有序数据的抽象接口，用于以连续方式异步读取或写入数据。它们特别适合处理大文件、网络通信或任何可能无限产生的数据。Node.js 内置的 stream 模块提供了四种基本流类型，以及用于组合和错误处理的工具函数。",{"path":2946,"title":2947,"description":2948,"category":10,"score":981},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fother","其他常用模块","以下是 Node.js 中几个重要内置模块的详细介绍，涵盖事件触发器、定时器、加密、压缩、操作系统信息和实用工具。",{"series":2950,"title":2951,"items":2952,"index":953,"prev":2966,"next":2967},"booklet\u002Fend\u002Fnodejs\u002Fcore","core",[2953,2955,2957,2959,2961,2963,2964],{"path":2930,"title":2931,"date":2954,"pinned":15},"2025-01-30",{"path":2926,"title":2927,"date":2956,"pinned":15},"2026-06-04",{"path":2938,"title":2939,"date":2958,"pinned":15},"2023-01-27",{"path":2946,"title":2947,"date":2960,"pinned":15},"2020-03-27",{"path":2934,"title":2935,"date":2962,"pinned":15},"2024-03-14",{"path":7,"title":8,"date":14,"pinned":15},{"path":2942,"title":2943,"date":2965,"pinned":15},"2022-05-03",{"path":2934,"title":2935,"date":2962,"pinned":15},{"path":2942,"title":2943,"date":2965,"pinned":15}]