{"id":339991,"date":"2022-10-20T09:00:37","date_gmt":"2022-10-20T09:00:37","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=339991"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=339991","title":{"rendered":"<span>\u041f\u0440\u0438\u0440\u0443\u0447\u0430\u0435\u043c \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0432 Node.js (\u0447\u0430\u0441\u0442\u044c 5: \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443)<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u0446\u0438\u043a\u043b\u0430 \u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 <a href=\"\/ru\/post\/689144\/\">\u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b<\/a> \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0432 JavaScript \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u0440\u0435\u0434\u044b Node.js;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0443\u044e <a href=\"\/ru\/post\/689406\/\">\u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u043a\u0430\u043d\u0430\u043b\u044b<\/a> \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 <a href=\"\/ru\/post\/689864\/\">\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u0438 Atomics-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/a> \u043a\u0430\u043a \u0441\u0430\u043c\u043e\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043e\u0431\u043c\u0435\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <a href=\"\/ru\/post\/691352\/\">\u043f\u043e\u0442\u043e\u043a-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440<\/a>, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439, \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439, \u0447\u0430\u0441\u0442\u0438 \u044f \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <strong>\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441<\/strong>, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043f\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c &#8212; \u044d\u0442\u043e <strong>\u043d\u0435<\/strong> \u043f\u0440\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0430 \u043f\u0440\u043e <strong>\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435<\/strong> <strong>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/strong> \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u0435\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u0439\u0442\u0438. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 &#171;\u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445&#187; \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0439, \u0433\u0434\u0435 \u043e\u043f\u043b\u0430\u0442\u0430 \u0438\u0434\u0435\u0442 \u0437\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u043d\u044b\u0435 CPU \u0438 RAM.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/b14\/3b5\/9b3\/b143b59b393791523b341592f4110845.jpg\" width=\"2357\" height=\"1501\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b14\/3b5\/9b3\/b143b59b393791523b341592f4110845.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0412 <a href=\"\/ru\/post\/691352\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c <strong>\u0431\u043b\u043e\u043a\u0438 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong> \u0447\u0435\u0440\u0435\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u0442\u043e\u043a\u0430-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430, \u0438\u0437\u0431\u0430\u0432\u0438\u0432\u0448\u0435\u0433\u043e \u043d\u0430\u0441 \u043e\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4fd\/7c5\/d3c\/4fd7c5d3cf21cf9c652e01b97e7a637a.png\" alt=\"\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c\" title=\"\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c\" width=\"681\" height=\"265\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4fd\/7c5\/d3c\/4fd7c5d3cf21cf9c652e01b97e7a637a.png\"\/><figcaption>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c<\/figcaption><\/figure>\n<p>\u041d\u043e, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u0442 <strong>\u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e<\/strong> \u0438\u0437 \u0434\u0432\u043e\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u043d\u043e \u0438 \u0438\u0437 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0438\u043d\u0433\u0430, \u0430 \u0432\u043e\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u0443\u0434\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0432\u043e\u0432\u0441\u0435 \u043d\u0435\u0437\u0430\u0447\u0435\u043c.<\/p>\n<p>\u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432\u044b\u043d\u0435\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0434\u0438\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043b\u0430\u0441\u0441 <code>Coordinator<\/code>, \u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e &#8212; \u0432 <code>WorkersPool<\/code>:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e81\/9db\/15d\/e819db15d5cf66416e899bd737739d6c.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438\" title=\"\u0421\u0445\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438\" width=\"492\" height=\"284\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e81\/9db\/15d\/e819db15d5cf66416e899bd737739d6c.png\"\/><figcaption>\u0421\u0445\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438<\/figcaption><\/figure>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u0430 \u0441\u0445\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">if (isMainThread) {   const {Coordinator} = require(...);   const coordinator = new Coordinator(__filename, ...);   coordinator     .on('online', () => {       \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445       coordinator.postMessage(message);     })     .on('message', (result, message) => { \/\/ \u0443\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 [\u043f\u043e id] \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442       \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 \u043f\u0430\u0440\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c     }); } else {   const {workerType, port} = workerData;   switch (workerType) {     case 'coordinator':       const {WorkersPool} = require(__filename, ...);       const pool = new WorkersPool(...);       break;     case 'worker':       const {shared} = workerData;       \/\/ \u043c\u0430\u0433\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438       port.postMessage({id, ...});       break;   } }<\/code><\/pre>\n<h2>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u043b\u044f &#171;\u0443\u0432\u044f\u0437\u043a\u0438&#187; \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>\u0430\u0432\u0442\u043e\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043d\u044b\u0439<\/strong> <code>id<\/code>. \u041d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c \u0435\u0433\u043e &#8212; \u043c\u0430\u043b\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0431\u043b\u043e\u043a \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 <code>SharedArrayBuffer<\/code>, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <strong>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440<\/strong> \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c-\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e <strong>\u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440<\/strong> \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0442\u043e\u0436\u0435, \u0438\u043d\u0430\u0447\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e &#171;\u0432\u044b\u0446\u0435\u043f\u0438\u0442\u044c&#187; \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0432 \u043f\u043e\u0442\u043e\u043a \u0431\u043b\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c <strong>\u043f\u0440\u0435\u0444\u0438\u043a\u0441<\/strong>, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u043e\u0433\u043e <code>id<\/code> \u0438 \u0434\u043b\u0438\u043d\u044b \u0441\u0430\u043c\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043c\u0435\u0442\u044c <code>Uint32Array<\/code> \u0438\u0437  \u0434\u0432\u0443\u0445 \u044f\u0447\u0435\u0435\u043a.<\/p>\n<p>\u041d\u043e \u0434\u043b\u044f &#171;\u0441\u043a\u043b\u0435\u0439\u043a\u0438&#187; \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0435\u0433\u043e <code>Uint8Array<\/code>-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044f \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>dataFunc<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"javascript\">message => { \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   \/\/ \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435   const buf = Buffer.concat([ui8prefix, ...message.part]);   \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043b\u0438\u043d\u0443   buf.writeUInt32LE(buf.length - 8, 4); \/\/ Uint32Array.BYTES_PER_ELEMENT   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442   return buf.buffer; }<\/code><\/pre>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f <code>id<\/code> \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a <code>Int32<\/code>-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u0432\u043e\u0435!), \u043d\u043e \u0438 \u043a\u0430\u043a \u044f\u0447\u0435\u0439\u043a\u0430 \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">const {shared} = workerData;  \/\/ [shared] = {lock:int32} + {size:uint32} + {data:uint8[]} const lock = new Int32Array(shared, 0, 1); const size = new Uint32Array(shared, Int32Array.BYTES_PER_ELEMENT, 1); const data = new Uint8Array(shared, Int32Array.BYTES_PER_ELEMENT + Uint32Array.BYTES_PER_ELEMENT); \/\/ ...   const id = lock[0];   const messageData = data.subarray(0, size[0]);<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a84\/b84\/957\/a84b84957579b02ac3b80c7823967557.png\" alt=\"\u0420\u0430\u0437\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\" title=\"\u0420\u0430\u0437\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\" width=\"867\" height=\"360\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a84\/b84\/957\/a84b84957579b02ac3b80c7823967557.png\"\/><figcaption>\u0420\u0430\u0437\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0432\u044b\u0448\u0435 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0435\u0439 \u043e\u0431\u043c\u0435\u043d\u0430 \u044d\u0442\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d5e\/156\/243\/d5e156243732ae53a0492e1cfa9d9881.png\" alt=\"\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c\" title=\"\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c\" width=\"1040\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d5e\/156\/243\/d5e156243732ae53a0492e1cfa9d9881.png\"\/><figcaption>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c<\/figcaption><\/figure>\n<ol>\n<li>\n<p>\u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <code>message<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0435\u0433\u043e \u0432 <code>Coordinator<\/code>, \u0433\u0434\u0435 \u043e\u043d\u043e \u043f\u043e <strong>\u0430\u0432\u0442\u043e\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043d\u043e\u043c\u0443<\/strong> <code>id<\/code> \u0437\u0430\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 <code>Map<\/code>-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 <code>messages<\/code><\/p>\n<\/li>\n<li>\n<p>\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>dataFunc<\/code> \u043c\u044b \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 &#171;\u0441\u043a\u043b\u0435\u0438\u0432\u0430\u0435\u043c&#187; \u0438\u0445 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c <code>id<\/code> <strong>\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 <code>data<\/code>-\u0431\u0443\u0444\u0435\u0440 \u043c\u044b <strong>\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/strong> \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043f\u043e\u0442\u043e\u043a-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043b\u0438 \u043f\u0440\u043e\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u044c (\u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u0437\u0430\u043d\u044f\u0442\u044b), \u0438\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 <strong>\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c<\/strong> \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u043d\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <strong>\u043f\u0440\u044f\u043c\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439<\/strong> \u043f\u043e\u0442\u043e\u043a, &#8230;<\/p>\n<\/li>\n<li>\n<p>&#8230; \u0433\u0434\u0435 \u043e\u043d\u0438 \u043f\u043e <code>id<\/code> \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 <code>.emit<\/code><\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u041a\u043b\u0430\u0441\u0441 Coordinator<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class Coordinator extends Worker {   #messages = new Map(); \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439    #p32 = new Uint32Array(2);               \/\/ \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u0430\u043d\u043d\u044b\u0445 = [messageID, dataSize]   #p8  = new Uint8Array(this.#p32.buffer); \/\/ ... \u0438 \u0435\u0433\u043e uint8-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044f   #data = [this.#p8]; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u0447\u0430\u0441\u0442\u0435\u0439 \u0432 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u0431\u043b\u043e\u043a   #message2data;      \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432    #data2buffer() {     \/\/ \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435     const buf = Buffer.concat(this.#data);     \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043b\u0438\u043d\u0443     buf.writeUInt32LE(buf.length - 8, 4); \/\/ Uint32Array.BYTES_PER_ELEMENT     \/\/ \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430     this.#data.length = 1;     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442     return buf.buffer;   };    constructor(filename, options) {     \/\/ \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b     const {port1, port2} = new MessageChannel();      \/* \u0434\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u043f\u0446\u0438\u0438       {         workerData : {           workerType : 'coordinator'         , port       : port2         }       , transferList : [port2]       }     *\/     ((options ??= {}).workerData ??= {}).workerType = 'coordinator';     ((options ??= {}).workerData ??= {}).port = port2;     ((options ??= {}).transferList ??= []).push(port2);     super(filename, options);      const {dataField, dataArray} = options;     this.#p32[0] = 0; \/\/ ID      this.#message2data = dataField       ? message => this.#data.push(dataField(message))       : message => this.#data.push(...dataArray(message));      const messages = this.#messages;     port1.on('message', ({threadId, port}) => {       \/\/ \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0438\u0439\u0441\u044f \u043f\u043e\u0440\u0442 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c       port.threadId = threadId;       this.emit('port.open', port);        port         .on('message', result => {           \/\/ \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e ID \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 ...           const message = messages.get(result.id);           if (message) {             messages.delete(result.id);             \/\/ ... \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c             this.emit('message', result, message);           }         })         .on('close', () => {           \/\/ \u043f\u0440\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u043f\u043e\u0440\u0442\u0430 - \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u043d\u0435\u0433\u043e           this.emit('port.close', port);           port.removeAllListeners();         });     });   }    \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a   postMessage(message) {     \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     this.#messages.set(this.#p32[0], message);     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u043e\u0434\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439     this.#message2data(message);     \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445     const buffer = this.#data2buffer();     \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \u0432 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435     super.postMessage(buffer, [buffer]);     \/\/ id = (id + 1) % 0x10000000     this.#p32[0]++;     this.#p32[0] &amp;= 0x0FFFFFFF;   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u0447\u0442\u043e \u0442\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c <code>Coordinator<\/code> \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u043c-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043f\u043e\u0434\u043d\u044f\u043b\u0438 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 <code>MessageChannel<\/code>, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043f\u0430\u0440\u044b \u043f\u043e\u0440\u0442\u043e\u0432, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u043e <a href=\"\/ru\/post\/689406\/\">\u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443 \u043f\u043e\u0442\u043e\u043a-<strong>\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u0440\u0442\u044b<\/strong> \u0434\u043b\u044f \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0445 \u0438\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e \u044d\u0442\u0438\u043c-\u0442\u043e \u043f\u043e\u0440\u0442\u0430\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442 \u043d\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u0432\u043e\u0435\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 <strong>\u043f\u0440\u044f\u043c\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fb6\/47b\/dd1\/fb647bdd13b179d5a2c298157fb13272.png\" alt=\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 MessageChannel\" title=\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 MessageChannel\" width=\"738\" height=\"719\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fb6\/47b\/dd1\/fb647bdd13b179d5a2c298157fb13272.png\"\/><figcaption>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 MessageChannel<\/figcaption><\/figure>\n<h2>\u0420\u0430\u0437\u0443\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/h2>\n<p>\u0422\u0430\u043a, \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a &#8212; \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c. \u041d\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435?<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 <strong>\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0441\u0442\u043e\u0438\u0442 \u0443\u0436\u0435 \u0441\u0430\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0430<\/strong>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043e\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043a\u0430\u043a\u0443\u044e-\u0442\u043e &#171;\u0442\u044f\u0436\u0435\u043b\u0443\u044e&#187; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0432\u0440\u043e\u0434\u0435 \u043f\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u044d\u0448\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430, \u0442\u043e \u0435\u0433\u043e \u0441\u0442\u0430\u0440\u0442 \u043c\u043e\u0436\u0435\u0442 \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u044f\u0434\u0440\u043e CPU \u0434\u0430\u0436\u0435 <strong>\u043d\u0430 \u0432\u0441\u0435 100%<\/strong>.<\/p>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u044b\u0432\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a\u0438 \u0441\u0442\u043e\u0438\u0442 <strong>\u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c\/\u0443\u0431\u0438\u0432\u0430\u0442\u044c<\/strong> <strong>\u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0436\u0435<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f <strong>\u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\/\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435<\/strong> \u043f\u043e\u0442\u043e\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, <strong>\u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c<\/strong> \u0432\u0441\u0435\u0433\u0434\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c <strong>\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c CPU-\u044f\u0434\u0435\u0440<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437 \u0443\u0436 \u043c\u044b \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b\u0438 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430 \u043c\u043e\u0433\u0443\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u043a\u044d\u0448, \u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043b\u0438\u0448\u044c <strong>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/strong>, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0434\u043e\u043b\u044e<code>cache hit<\/code>.<\/p>\n<p>\u041a\u0430\u043a \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0448\u0435, \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0435\u0442 \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>WorkersPool<\/code>, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 <strong>\u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e.<\/p>\n<h2>\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 &#171;\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438&#187;<\/h2>\n<p>\u041d\u043e \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0443\u0436\u0435 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0432\u0441\u0435 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0438?<\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 &#8212; \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c <strong>\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e<\/strong>. \u0410 \u043b\u044e\u0431\u0430\u044f \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u0434\u0430\u043d\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u043c\u0443-\u0442\u043e \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043b\u0438\u0431\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 <strong>\u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/strong>.<\/p>\n<p>\u041e\u0447\u0435\u0440\u0435\u0434\u044c, \u043a\u0441\u0442\u0430\u0442\u0438, \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0432\u0441\u0435 \u0442\u0443 \u0436\u0435, \u0438\u0437 <a href=\"\/ru\/post\/689864\/\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438<\/a>, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"\/ru\/post\/688182\/\">\u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430<\/a>:<\/p>\n<pre><code class=\"javascript\">this.#queue = new (require('.\/Pow2Buffer'))(queuePowMin, queuePowMax);<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u0434\u043b\u0438\u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 &#171;\u0432 \u0448\u0442\u0443\u043a\u0430\u0445&#187; \u043d\u0430\u043c \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u043e \u0447\u0435\u043c-\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0432\u0435\u0434\u044c \u043c\u044b \u043d\u0435 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u043c \u043d\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u0438 &#171;\u0432\u0435\u0441&#187; \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0434\u0443\u043c\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 1 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0430\u0441 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043d\u0430\u043f\u0440\u044f\u0433\u0430\u0435\u0442, \u0430 &#171;\u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435&#187; \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 1 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0432\u0441\u0435\u043c, \u0442\u043e \u0433\u0434\u0435-\u0442\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0435 <code>[1ms .. 1s]<\/code> \u043d\u0430\u0439\u0434\u0435\u043c <strong>\u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/strong>, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0435\u0437\u0431\u043e\u043b\u0435\u0437\u043d\u0435\u043d\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 &#8212; \u0441\u043a\u0430\u0436\u0435\u043c, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 <code>100ms<\/code>.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043a\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0435\u0431\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0430\u0440\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0432\u0430\u043b\u0438\u043b\u043e \u0437\u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u0435\u0449\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0436\u0434\u0430\u0442\u044c, \u0447\u0435\u043c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u043e\u0446\u0435\u043d\u043a\u043e\u0439 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043f\u043e\u0432\u0435\u0441\u0438\u043c \u044d\u0442\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0442\u0430\u0439\u043c\u0435\u0440 \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043b\u0430\u0441\u0441 WorkersPool (\u043a\u0430\u0440\u043a\u0430\u0441)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class WorkersPool {   #options; \/\/ \u043a\u044d\u0448 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430    #mainWorker;              \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a   #workersPool = [];        \/\/ \u043f\u0443\u043b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432   #workersSet  = new Set(); \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432   #workersRemain;           \/\/ \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0435\u0449\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e    #queue;      \/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435    #checking;   \/\/ \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f    #queueMore1; \/\/ \"\u0434\u043b\u0438\u043d\u0430\" \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 1 \u043f\u043e\u0442\u043e\u043a\u0430   #queueMoreW; \/\/                                   ... \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432    #checkQueue(workers) {     \/\/ \u0435\u0441\u043b\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u0447 \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0432,     \/\/ ... \u0438 \u0441\u0430\u043c\u0430\u044f \u0441\u0442\u0430\u0440\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u0438\u0441\u0438\u0442 \u0434\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0431\u044b \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043d\u043e\u0432\u043e\u0433\u043e     return this.#queue.length > workers &amp;&amp; this.#queue[0].ts + this.#options['timeoutSpawn'] * workers &lt; Date.now();   }    constructor(workerFile, options) {     options['workerFile'] ??= workerFile;     const {poolSize, queuePowMin, queuePowMax, timeoutIdle, intervalCheck} = options;     this.#options = options;      this.#workersRemain = poolSize;      \/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435     this.#queue = new (require('.\/Pow2Buffer'))(queuePowMin, queuePowMax);      \/\/ \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u0438 \u0432\u0441\u0435\u0433\u0434\u0430     this.#mainWorker = this.#createWorker();          \/\/ ...          \/\/ \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043f\u0443\u043b\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432     const pool = this.#workersPool;     setInterval(() => {       \/\/ \u043f\u043e\u0440\u0430 \u043b\u0438 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a?       this.#queueMoreW = this.#checkQueue(this.#workersSet.size);       \/\/ \u043f\u043e\u0440\u0430 \u043b\u0438 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c?       this.#queueMore1 = this.#queueMoreW || this.#checkQueue(1);       \/\/ \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0430\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432       \/\/ ...     }, intervalCheck);   }    #createWorkerIfPossible() {     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c (\u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u043c\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u0438) \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u0442\u043e\u043a\u0430     if (this.#workersRemain > 0 &amp;&amp; this.#checkQueue(this.#workersSet.size)) {       this.#createWorker();     }   }    #createWorker() {     this.#workersRemain--;     this.#workersRemain = -this.#workersRemain; \/\/ wrap flag     \/\/ ...      worker.on('online', () => {       \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0443\u0437\u044b \u043d\u0430 timeoutSpawn       setTimeout(() => {         this.#workersRemain = -this.#workersRemain; \/\/ wrap flag         this.#createWorkerIfPossible();       }, this.#options['timeoutSpawn']);     });      return worker;   }    #destroyWorker(worker) {     \/\/ \u0443\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430     this.#workersSet.delete(worker);     \/\/ \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0441\u0430\u043c \u043f\u043e\u0442\u043e\u043a     worker.terminate();     \/\/ \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0440\u043a\u0435\u0440 \u0438\u0437 \u043f\u0443\u043b\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u0442\u0430\u043c \u0431\u044b\u043b     const idx = this.#workersPool.indexOf(worker);     if (idx >= 0) {       this.#workersPool.splice(idx, 1);     }     \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443     this.#workersRemain++;   } }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 <code>#workersRemain<\/code> \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u043a\u0430\u043a \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443, \u0438 \u043a\u0430\u043a \u043f\u0440\u0438\u0437\u043d\u0430\u043a (\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435) \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0442\u043e\u043a\u0430.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0443\u043b\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0430 \u043d\u0435 Set, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u0432\u0430\u0436\u0435\u043d \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0438\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/h2>\n<blockquote>\n<p>\u0421\u0442\u0430\u0440\u0448\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u043c\u0435\u043b\u044c\u043d\u0438\u0446\u0430, \u0441\u0440\u0435\u0434\u043d\u0435\u043c\u0443 \u2013 \u043e\u0441\u0435\u043b, \u043d\u0443 \u0430 \u043c\u043b\u0430\u0434\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u0437\u044f\u0442\u044c \u0441\u0435\u0431\u0435 \u043a\u043e\u0442\u0430.<\/p>\n<p>[\u0428\u0430\u0440\u043b\u044c \u041f\u0435\u0440\u0440\u043e, &#171;\u041a\u043e\u0442 \u0432 \u0441\u0430\u043f\u043e\u0433\u0430\u0445&#187;]<\/p>\n<\/blockquote>\n<p>\u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043d\u0430\u043c \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435 &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 <strong>\u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u043e\u043b\u044c\u0448\u0435<\/strong>.<\/p>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f <strong>\u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043a\u0430\u043a \u043c\u044b \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438\u0441\u044c \u0432\u044b\u0448\u0435, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430.<\/p>\n<p>\u041d\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043d\u044f\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 &#8212; \u0442\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443, \u0435\u0441\u043b\u0438 &#171;\u0434\u043b\u0438\u043d\u0430&#187; \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0443\u0436\u0435 \u0437\u0430\u0432\u0435\u0434\u043e\u043c\u043e \u043f\u0440\u0435\u0432\u043e\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c, \u0438 \u043e\u0431\u0449\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0437\u0430 \u043d\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430, \u0442\u043e \u043f\u043e\u0440\u0430 \u0437\u0430\u0434\u0443\u043c\u0430\u0442\u044c\u0441\u044f \u043e \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430:<\/p>\n<pre><code class=\"javascript\">this.#queueMoreW &amp;&amp; this.#workersRemain > 0 &amp;&amp; (this.#checking ??= setTimeout(() => {   this.#createWorkerIfPossible();   this.#checking = null; }, this.#options['intervalCheck']));<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0436\u0434\u0430\u0442\u044c <code>intervalCheck<\/code> \u0434\u043b\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u0442\u043e\u043a\u0430, \u043d\u043e \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0435.<\/p>\n<h2>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439<\/h2>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430\u0434\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0438\u0445, \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0434\u0432\u0435.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f <code>parentPort.on('message', message => ...)<\/code>, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u043e \u0438 \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0435 \u0437\u0430 \u043d\u0438\u043c \u043c\u043e\u0433\u043b\u0438 \u0443\u0441\u043f\u0435\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0447\u0435\u0440\u0435\u0437 <code>receiveMessageOnPort<\/code>, \u0438\u0437\u0431\u0435\u0433\u043d\u0443\u0432 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u0430\u043a \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u043e\u0441\u044c <a href=\"\/ru\/post\/689406\/\">\u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0438\u043d\u0433\u0430 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/319\/6b8\/00f\/3196b800f13dd4c81d5223784b64cd93.png\" alt=\"&quot;\u0412\u044b\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u0435\u043c&quot; \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\" title=\"&quot;\u0412\u044b\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u0435\u043c&quot; \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\" width=\"643\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/319\/6b8\/00f\/3196b800f13dd4c81d5223784b64cd93.png\"\/><figcaption>&#171;\u0412\u044b\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u0435\u043c&#187; \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>.on(&#8216;message&#8217;) \u0438 .pulse()<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">  constructor(workerFile, options) {     \/\/ ...          \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u0438\u0435\u043c\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 main-\u043f\u043e\u0442\u043e\u043a\u0430     parentPort.on('message', message => {       \/\/ \u0444\u043b\u0430\u0433 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443       let processed;       const {lock : [lockState], _pulse} = this.#mainWorker;       if (lockState == THREAD_FREE) { \/\/ \u0435\u0441\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0432\u043e\u0431\u043e\u0434\u0435\u043d         processed = _pulse(message);  \/\/ ... \u043e\u0442\u0434\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443         message = undefined;          \/\/ ... \u0438 \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c       }       \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \"\u0434\u0435\u0440\u0433\u0430\u0442\u044c\" \u043f\u043e\u0442\u043e\u043a\u0438, \u043f\u043e\u043a\u0430 \u0445\u043e\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u044c (\u043f\u043e\u0440\u0442\u0430 \u0438\u043b\u0438 \u0441\u0432\u043e\u044f) \u043d\u0435\u043f\u0443\u0441\u0442\u0430       \/\/ ... \u0438 \u0435\u0449\u0435 \u043a\u0442\u043e-\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043a\u0442\u043e-\u0442\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439       while (!processed) {         const worker = this.#queueMore1 &amp;&amp; this.#workersPool.pop();         if (worker) {           processed = worker._pulse(message);           message &amp;&amp;= undefined;         }         else {           \/\/ \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u043c\u0435\u0442\u043a\u043e\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438           const now = Date.now();           message ??= receiveMessageOnPort(parentPort)?.message;           while (message) {             this.#queue.push(message);             message.ts = now;             message = receiveMessageOnPort(parentPort)?.message;           }           \/\/ \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430           this.#queueMoreW &amp;&amp; this.#workersRemain > 0 &amp;&amp; (this.#checking ??= setTimeout(() => {             this.#createWorkerIfPossible();             this.#checking = null;           }, this.#options['intervalCheck']));           return;         }       }     });   }   \/\/ ...    #pulseWorker(worker, message) {     \/\/ \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 - \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0443     let processed = !message || worker._send(message);     \/\/ \u043f\u043e\u043a\u0430 \u043e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \"\u0443\u0436\u0435 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\"...     while (processed) {       \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e\u0440\u0442\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430       const recv = receiveMessageOnPort(parentPort);       \/\/ ... \u0438\u043b\u0438 \u0441\u0432\u043e\u0435\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438       message = recv?.message ?? this.#queue.shift();       if (!message) {         if (worker !== this.#mainWorker) {           \/\/ \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438\u0441\u044c - \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0432 \u043f\u0443\u043b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445           const pool = this.#workersPool;           !pool.includes(worker) &amp;&amp; pool.push(worker);         }         return true;       }       \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a       processed = worker._send(message);     }   }; <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0430\u043c\u0430 \u0441\u0445\u0435\u043c\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0432 \u043f\u043e\u0442\u043e\u043a &#171;\u043f\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435&#187; \u0442\u0430 \u0436\u0435 \u0441\u0430\u043c\u0430\u044f, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 <a href=\"\/ru\/post\/691352\/\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>.<\/p>\n<h2>&#171;\u041c\u043e\u044f \u0444\u0430\u043c\u0438\u043b\u0438\u044f &#8212; \u0418\u0442\u043e\u0433\u043e&#187;<\/h2>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u043e\u0435\u0434\u0438\u043d\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const {   Worker , isMainThread , parentPort , workerData , MessageChannel , receiveMessageOnPort , threadId } = require('node:worker_threads');  const THREAD_FREE = -1;  class WorkersPool {   #options; \/\/ \u043a\u044d\u0448 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430    #mainWorker;              \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a   #workersPool = [];        \/\/ \u043f\u0443\u043b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432   #workersSet  = new Set(); \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432   #workersRemain;           \/\/ \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0435\u0449\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e    #queue;      \/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435    #checking;   \/\/ \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f    #queueMore1; \/\/ \"\u0434\u043b\u0438\u043d\u0430\" \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 1 \u043f\u043e\u0442\u043e\u043a\u0430   #queueMoreW; \/\/                                   ... \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432    #checkQueue(workers) {     \/\/ \u0435\u0441\u043b\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u0447 \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0432,     \/\/ ... \u0438 \u0441\u0430\u043c\u0430\u044f \u0441\u0442\u0430\u0440\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u0438\u0441\u0438\u0442 \u0434\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0431\u044b \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043d\u043e\u0432\u043e\u0433\u043e     return this.#queue.length > workers &amp;&amp; this.#queue[0].ts + this.#options['timeoutSpawn'] * workers &lt; Date.now();   }    constructor(workerFile, options) {     options['workerFile'] ??= workerFile;     const {poolSize, queuePowMin, queuePowMax, timeoutIdle, intervalCheck} = options;     this.#options = options;      this.#workersRemain = poolSize;      \/\/ \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435     this.#queue = new (require('.\/Pow2Buffer'))(queuePowMin, queuePowMax);      \/\/ \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u0438 \u0432\u0441\u0435\u0433\u0434\u0430     this.#mainWorker = this.#createWorker();      \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u0438\u0435\u043c\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 main-\u043f\u043e\u0442\u043e\u043a\u0430     parentPort.on('message', message => {       \/\/ \u0444\u043b\u0430\u0433 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443       let processed;       const {lock : [lockState], _pulse} = this.#mainWorker;       if (lockState == THREAD_FREE) { \/\/ \u0435\u0441\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0432\u043e\u0431\u043e\u0434\u0435\u043d         processed = _pulse(message);  \/\/ ... \u043e\u0442\u0434\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443         message = undefined;          \/\/ ... \u0438 \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c       }       \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \"\u0434\u0435\u0440\u0433\u0430\u0442\u044c\" \u043f\u043e\u0442\u043e\u043a\u0438, \u043f\u043e\u043a\u0430 \u0445\u043e\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u044c (\u043f\u043e\u0440\u0442\u0430 \u0438\u043b\u0438 \u0441\u0432\u043e\u044f) \u043d\u0435\u043f\u0443\u0441\u0442\u0430       \/\/ ... \u0438 \u0435\u0449\u0435 \u043a\u0442\u043e-\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043a\u0442\u043e-\u0442\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439       while (!processed) {         const worker = this.#queueMore1 &amp;&amp; this.#workersPool.pop();         if (worker) {           processed = worker._pulse(message);           message &amp;&amp;= undefined;         }         else {           \/\/ \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0440\u0442\u0430 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u043c\u0435\u0442\u043a\u043e\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438           const now = Date.now();           message ??= receiveMessageOnPort(parentPort)?.message;           while (message) {             this.#queue.push(message);             message.ts = now;             message = receiveMessageOnPort(parentPort)?.message;           }           \/\/ \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430           this.#queueMoreW &amp;&amp; this.#workersRemain > 0 &amp;&amp; (this.#checking ??= setTimeout(() => {             this.#createWorkerIfPossible();             this.#checking = null;           }, this.#options['intervalCheck']));           return;         }       }     });      \/\/ \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043f\u0443\u043b\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432     const pool = this.#workersPool;     setInterval(() => {       \/\/ \u043f\u043e\u0440\u0430 \u043b\u0438 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a?       this.#queueMoreW = this.#checkQueue(this.#workersSet.size);       \/\/ \u043f\u043e\u0440\u0430 \u043b\u0438 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c?       this.#queueMore1 = this.#queueMoreW || this.#checkQueue(1);       \/\/ \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0430\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432       if (pool.length) {         const deadline = Date.now() - timeoutIdle;         for (const {activity, lock : [lockState], _destroy} of pool) {           activity &lt; deadline &amp;&amp; lockState == THREAD_FREE &amp;&amp; _destroy();         }       }     }, intervalCheck);   }    #createWorkerIfPossible() {     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c (\u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u043c\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u0438) \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u0442\u043e\u043a\u0430     if (this.#workersRemain > 0 &amp;&amp; this.#checkQueue(this.#workersSet.size)) {       this.#createWorker();     }   }    #createWorker() {     this.#workersRemain--;     this.#workersRemain = -this.#workersRemain; \/\/ wrap flag      const shared = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT + Uint32Array.BYTES_PER_ELEMENT + this.#options['dataSize']);     const data = new Uint8Array(shared);     const lock = new Int32Array(shared, 0, 1); \/\/ lock\/id - \u043f\u0435\u0440\u0432\u044b\u0435 4 \u0431\u0430\u0439\u0442\u0430 data     lock[0] = 0;      \/\/ \u0436\u0434\u0435\u043c, \u043f\u043e\u043a\u0430 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u0441\u043c\u0435\u043d\u0438\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \"\u043f\u043e\u0434\u0435\u0440\u0433\u0430\u0442\u044c\"     let worker;     Atomics.waitAsync(lock, 0, 0)       .value       .then(() => lock[0] == THREAD_FREE &amp;&amp; worker._pulse());          const {port1, port2} = new MessageChannel();     worker = new Worker(       this.#options['workerFile']     , {         workerData : {           workerType : 'worker'         , shared         , port       : port2 \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u043e\u0440\u0442 \u0432 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a         }       , transferList : [port2]       }     );      \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0440\u0442 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a, \u0432 Coordinator     this.#options['port'].postMessage(       {         threadId : worker.threadId       , port     : port1       }     , [port1]     );      this.#workersSet.add(worker);      worker.id = worker.threadId;     worker.port = port2;     worker.lock = lock;     worker.data = data;      worker._pulse   = this.#pulseWorker.bind(this, worker);     worker._destroy = this.#destroyWorker.bind(this, worker);     worker._send    = this.#sendMessage.bind(this, worker);      worker.on('online', () => {       \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0443\u0437\u044b \u043d\u0430 timeoutSpawn       setTimeout(() => {         this.#workersRemain = -this.#workersRemain; \/\/ wrap flag         this.#createWorkerIfPossible();       }, this.#options['timeoutSpawn']);     });      return worker;   }    #pulseWorker(worker, message) {     \/\/ \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 - \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0443     let processed = !message || worker._send(message);     \/\/ \u043f\u043e\u043a\u0430 \u043e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \"\u0443\u0436\u0435 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\"...     while (processed) {       \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e\u0440\u0442\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430       const recv = receiveMessageOnPort(parentPort);       \/\/ ... \u0438\u043b\u0438 \u0441\u0432\u043e\u0435\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438       message = recv?.message ?? this.#queue.shift();       if (!message) {         if (worker !== this.#mainWorker) {           \/\/ \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438\u0441\u044c - \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0432 \u043f\u0443\u043b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445           const pool = this.#workersPool;           !pool.includes(worker) &amp;&amp; pool.push(worker);         }         return true;       }       \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a       processed = worker._send(message);     }   };    #sendMessage(worker, message) {     const {lock, data, _pulse} = worker;     \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0437 ui8-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 id     data.set(new Uint8Array(message));     \/\/ id - \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0435 4 \u0431\u0430\u0439\u0442\u0430 data     const id = lock[0];     \/\/ \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c \u043f\u043e\u0442\u043e\u043a     Atomics.notify(lock, 0, 1);     \/\/ \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0442\u043e\u043a\u0430     worker.activity = Date.now();     \/\/ \u0436\u0434\u0435\u043c, \u043f\u043e\u043a\u0430 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043d\u0435 \u043f\u043e\u0437\u043e\u0432\u0435\u0442 \u043d\u0430\u0441     const {value} = Atomics.waitAsync(lock, 0, id);     if (value === 'not-equal') {       \/\/ \u0435\u0441\u043b\u0438 \u043e\u043d \u0441\u0440\u0430\u0437\u0443 \u0443\u0441\u043f\u0435\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0442\u043e \u0432 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u0438\u0441\u0430\u0442\u044c       return true;     }     else {       \/\/ \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443 - \"\u043f\u043e\u0434\u0435\u0440\u0433\u0430\u0435\u043c\", \u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u0441\u044f       value.then(() => lock[0] == THREAD_FREE &amp;&amp; _pulse());     }   }    #destroyWorker(worker) {     \/\/ \u0443\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430     this.#workersSet.delete(worker);     \/\/ \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e MessageChannel     worker.port.close();     \/\/ \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0441\u0430\u043c \u043f\u043e\u0442\u043e\u043a     worker.terminate();     \/\/ \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0440\u043a\u0435\u0440 \u0438\u0437 \u043f\u0443\u043b\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u0442\u0430\u043c \u0431\u044b\u043b     const idx = this.#workersPool.indexOf(worker);     if (idx >= 0) {       this.#workersPool.splice(idx, 1);     }     \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443     this.#workersRemain++;   } }  class Coordinator extends Worker {   #messages = new Map(); \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439    #p32 = new Uint32Array(2);               \/\/ \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u0430\u043d\u043d\u044b\u0445 = [messageID, dataSize]   #p8  = new Uint8Array(this.#p32.buffer); \/\/ ... \u0438 \u0435\u0433\u043e uint8-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044f   #data = [this.#p8]; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u0447\u0430\u0441\u0442\u0435\u0439 \u0432 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u0431\u043b\u043e\u043a   #message2data;      \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432    #data2buffer() {     \/\/ \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435     const buf = Buffer.concat(this.#data);     \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043b\u0438\u043d\u0443     buf.writeUInt32LE(buf.length - 8, 4); \/\/ Uint32Array.BYTES_PER_ELEMENT     \/\/ \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430     this.#data.length = 1;     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442     return buf.buffer;   };    constructor(filename, options) {     \/\/ \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b     const {port1, port2} = new MessageChannel();      \/* \u0434\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u043f\u0446\u0438\u0438       {         workerData : {           workerType : 'coordinator'         , port       : port2         }       , transferList : [port2]       }     *\/     ((options ??= {}).workerData ??= {}).workerType = 'coordinator';     ((options ??= {}).workerData ??= {}).port = port2;     ((options ??= {}).transferList ??= []).push(port2);     super(filename, options);      const {dataField, dataArray} = options;     this.#p32[0] = 0; \/\/ ID      this.#message2data = dataField       ? message => this.#data.push(dataField(message))       : message => this.#data.push(...dataArray(message));      const messages = this.#messages;     port1.on('message', ({threadId, port}) => {       \/\/ \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0438\u0439\u0441\u044f \u043f\u043e\u0440\u0442 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c       port.threadId = threadId;       this.emit('port.open', port);        port         .on('message', result => {           \/\/ \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e ID \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 ...           const message = messages.get(result.id);           if (message) {             messages.delete(result.id);             \/\/ ... \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c             this.emit('message', result, message);           }         })         .on('close', () => {           \/\/ \u043f\u0440\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u043f\u043e\u0440\u0442\u0430 - \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u043d\u0435\u0433\u043e           this.emit('port.close', port);           port.removeAllListeners();         });     });   }    \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a   postMessage(message) {     \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     this.#messages.set(this.#p32[0], message);     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u043e\u0434\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439     this.#message2data(message);     \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445     const buffer = this.#data2buffer();     \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \u0432 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435     super.postMessage(buffer, [buffer]);     \/\/ id = (id + 1) % 0x10000000     this.#p32[0]++;     this.#p32[0] &amp;= 0x0FFFFFFF;   } }  const taskSize = 1 &lt;&lt; 16;  if (isMainThread) {   const {randomBytes} = require('node:crypto');   const fs = require('node:fs');   const {tmpdir} = require('node:os');   const {sep} = require('node:path');    console.log(Date.now(), 'Main : online');   const messages = Array(1 &lt;&lt; 12).fill().map(_ => randomBytes(taskSize));    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0438 \u0432 \u043d\u0435\u0439 \u0444\u0430\u0439\u043b\u044b \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \"\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438\"   const dir = fs.mkdtempSync(tmpdir() + sep);   messages.forEach((data, i) => {     const fn = i.toString(16).padStart(3, '0');     fs.writeFileSync(dir + sep + fn, data);   });   console.log(Date.now(), 'Main : generated');    const hashes = messages.map(() => undefined);   let remain;    const coordinator = new Coordinator(     __filename   , {       dataField : message => message.data \/\/ \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u043b\u0435     }   );   coordinator     .on('online', () => {       console.log(Date.now(), 'Coordinator : online');       \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439       const fns = fs.readdirSync(dir)         .sort()         .map(fn => dir + sep + fn);       remain = fns.length;        fns.forEach((fn, id) => {         const data = fs.readFileSync(fn); \/\/ \u0442\u044f\u0436\u0435\u043b\u044b\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434         coordinator.postMessage({id, fn, data});       });       console.log(Date.now(), 'Main : all send');     })     .on('port.open', port => {       console.log(Date.now(), `Coordinator : dataPort open  = +1 worker [${port.threadId}]`);     })     .on('port.close', port => {       console.log(Date.now(), `Coordinator : dataPort close = -1 worker [${port.threadId}]`);     })     .on('message', (result, message) => {       hashes[message.id] = result.hash;       if (!--remain) {         console.log(Date.now(), 'Main : all recv');         \/\/ \u043f\u043e\u0434\u043e\u0436\u0434\u0435\u043c, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u0441\u044f \u0432\u0441\u0435 \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438         setTimeout(() => {           process.exit();         }, 1000);       }     }); } else {   const {workerType, port} = workerData;   switch (workerType) {     case 'coordinator':       \/\/ \u0432 \u043f\u043e\u0442\u043e\u043a\u0435-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0435 \u043d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438, \u043a\u0440\u043e\u043c\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0443\u043b\u043e\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432       const pool = new WorkersPool(         __filename       , {           poolSize      : require('node:os').cpus().length \/\/ \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 CPU-\u044f\u0434\u0435\u0440         , dataSize      : taskSize \/\/ \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445         , port         , queuePowMin   : 8  \/\/   256         , queuePowMax   : 16 \/\/ 65536         , intervalCheck : 10         , timeoutSpawn  : 100         , timeoutIdle   : 10         }       );       break;     case 'worker':       const {createHash} = require('node:crypto');        const {shared} = workerData;        \/\/ [shared] = {lock:int32} + {size:uint32} + {data:uint8[]}       const lock = new Int32Array(shared, 0, 1);       const size = new Uint32Array(shared, Int32Array.BYTES_PER_ELEMENT, 1);       const data = new Uint8Array(shared, Int32Array.BYTES_PER_ELEMENT + Uint32Array.BYTES_PER_ELEMENT);        const processMessage = () => {         \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435         port.postMessage({           id   : lock[0]              \/\/ \u0441\u0432\u044f\u0437\u0443\u044e\u0449\u0438\u0439 ID         , hash : createHash('sha256').update(             data.subarray(0, size[0]) \/\/ \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442           ).digest('hex')         });         \/\/ \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 \u043e \u0441\u0432\u043e\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438         lock[0] = THREAD_FREE;         Atomics.notify(lock, 0, 1);         \/\/ ... \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438         wait();       };        const wait = () => {         const {value} = Atomics.waitAsync(lock, 0, THREAD_FREE);         if (value === 'not-equal') {           \/\/ \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c, \u0442\u043e \u043f\u043e\u0442\u043e\u043a \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0438 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0437\u0443           processMessage();         }         else {           \/\/ \u0438\u043d\u0430\u0447\u0435 \u0436\u0434\u0435\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f Promise \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438           value.then(processMessage);         }       };        \/\/ \"\u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u043c\" \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430       lock[0] = THREAD_FREE;       Atomics.notify(lock, 0, 1);       wait();        \/\/ \u043f\u043e\u0434\u0432\u0435\u0448\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435       port.on('message', () => {});       break;   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<pre><code>1666250935654 Main : online 1666250940036 Main : generated 1666250940132 Coordinator : online 1666250941187 Main : all send 1666250941195 Coordinator : dataPort open  = +1 worker [2] 1666250941196 Coordinator : dataPort open  = +1 worker [3] 1666250941196 Coordinator : dataPort open  = +1 worker [4] 1666250941225 Coordinator : dataPort close = -1 worker [3] 1666250941244 Main : all recv 1666250941262 Coordinator : dataPort close = -1 worker [4]<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u044b\u043b\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0434\u043e 3 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432: \u0433\u043b\u0430\u0432\u043d\u044b\u0439 <code>#2<\/code> \u0438 \u0434\u0432\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 <code>#3<\/code> \u0438 <code>#4<\/code>. \u041e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0443\u0441\u043f\u0435\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u0436\u0435 \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 &#8212; \u0447\u0443\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u044f.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0432 JavaScript\/Node.js \u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e, \u0430 \u0432\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 &#8212; \u043d\u0435 \u043f\u043e\u0436\u0430\u043b\u0435\u0435\u0442\u0435!<\/p>\n<hr\/>\n<ul>\n<li>\n<p>\u0447\u0430\u0441\u0442\u044c 1:\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/689144\/\">\u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p>\u0447\u0430\u0441\u0442\u044c 2:\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/689406\/\"><u>\u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043a\u0430\u043d\u0430\u043b\u044b \u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440<\/u><\/a><\/p>\n<\/li>\n<li>\n<p>\u0447\u0430\u0441\u0442\u044c 3:\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/689864\/\">\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0430\u044f \u043f\u0430\u043c\u044f\u0442\u044c, \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p>\u0447\u0430\u0441\u0442\u044c 4:\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/691352\/\">\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0442\u0438\u0432 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/a><\/p>\n<\/li>\n<li>\n<p>\u0447\u0430\u0441\u0442\u044c 5: <a href=\"\/ru\/post\/693738\/\">\u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/693738\/\"> https:\/\/habr.com\/ru\/company\/tensor\/blog\/693738\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u0446\u0438\u043a\u043b\u0430 \u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 <a href=\"\/ru\/post\/689144\/\">\u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b<\/a> \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0432 JavaScript \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u0440\u0435\u0434\u044b Node.js;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0443\u044e <a href=\"\/ru\/post\/689406\/\">\u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u043a\u0430\u043d\u0430\u043b\u044b<\/a> \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 <a href=\"\/ru\/post\/689864\/\">\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u0438 Atomics-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/a> \u043a\u0430\u043a \u0441\u0430\u043c\u043e\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043e\u0431\u043c\u0435\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <a href=\"\/ru\/post\/691352\/\">\u043f\u043e\u0442\u043e\u043a-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440<\/a>, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0435\u0439, \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439, \u0447\u0430\u0441\u0442\u0438 \u044f \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <strong>\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441<\/strong>, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043f\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c &#8212; \u044d\u0442\u043e <strong>\u043d\u0435<\/strong> \u043f\u0440\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0430 \u043f\u0440\u043e <strong>\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435<\/strong> <strong>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/strong> \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u0435\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u0439\u0442\u0438. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 &#171;\u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445&#187; \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0439, \u0433\u0434\u0435 \u043e\u043f\u043b\u0430\u0442\u0430 \u0438\u0434\u0435\u0442 \u0437\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u043d\u044b\u0435 CPU \u0438 RAM.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0412 <a href=\"\/ru\/post\/691352\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c <strong>\u0431\u043b\u043e\u043a\u0438 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong> \u0447\u0435\u0440\u0435\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u0442\u043e\u043a\u0430-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430, \u0438\u0437\u0431\u0430\u0432\u0438\u0432\u0448\u0435\u0433\u043e \u043d\u0430\u0441 \u043e\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435:<\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c<\/figcaption><\/figure>\n<p>\u041d\u043e, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u0442 <strong>\u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e<\/strong> \u0438\u0437 \u0434\u0432\u043e\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u043d\u043e \u0438 \u0438\u0437 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0438\u043d\u0433\u0430, \u0430 \u0432\u043e\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u0443\u0434\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0432\u043e\u0432\u0441\u0435 \u043d\u0435\u0437\u0430\u0447\u0435\u043c.<\/p>\n<p>\u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432\u044b\u043d\u0435\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0434\u0438\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043b\u0430\u0441\u0441 <code>Coordinator<\/code>, \u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e &#8212; \u0432 <code>WorkersPool<\/code>:<\/p>\n<figure class=\"\"><figcaption>\u0421\u0445\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438<\/figcaption><\/figure>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u0430 \u0441\u0445\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">if (isMainThread) {   const {Coordinator} = require(...);   const coordinator = new Coordinator(__filename, ...);   coordinator     .on('online', () => {       \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445       coordinator.postMessage(message);     })     .on('message', (result, message) => { \/\/ \u0443\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 [\u043f\u043e id] \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442       \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 \u043f\u0430\u0440\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c     }); } else {   const {workerType, port} = workerData;   switch (workerType) {     case 'coordinator':       const {WorkersPool} = require(__filename, ...);       const pool = new WorkersPool(...);       break;     case 'worker':       const {shared} = workerData;       \/\/ \u043c\u0430\u0433\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438       port.postMessage({id, ...});       break;   } }<\/code><\/pre>\n<h2>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u043b\u044f &#171;\u0443\u0432\u044f\u0437\u043a\u0438&#187; \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>\u0430\u0432\u0442\u043e\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043d\u044b\u0439<\/strong> <code>id<\/code>. \u041d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c \u0435\u0433\u043e &#8212; \u043c\u0430\u043b\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0431\u043b\u043e\u043a \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 <code>SharedArrayBuffer<\/code>, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <strong>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440<\/strong> \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c-\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e <strong>\u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440<\/strong> \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0442\u043e\u0436\u0435, \u0438\u043d\u0430\u0447\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e &#171;\u0432\u044b\u0446\u0435\u043f\u0438\u0442\u044c&#187; \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0432 \u043f\u043e\u0442\u043e\u043a \u0431\u043b\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c <strong>\u043f\u0440\u0435\u0444\u0438\u043a\u0441<\/strong>, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u043e\u0433\u043e <code>id<\/code> \u0438 \u0434\u043b\u0438\u043d\u044b \u0441\u0430\u043c\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043c\u0435\u0442\u044c <code>Uint32Array<\/code> \u0438\u0437  \u0434\u0432\u0443\u0445 \u044f\u0447\u0435\u0435\u043a.<\/p>\n<p>\u041d\u043e \u0434\u043b\u044f &#171;\u0441\u043a\u043b\u0435\u0439\u043a\u0438&#187; \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0435\u0433\u043e <code>Uint8Array<\/code>-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044f \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>dataFunc<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"javascript\">message => { \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   \/\/ \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435   const buf = Buffer.concat([ui8prefix, ...message.part]);   \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043b\u0438\u043d\u0443   buf.writeUInt32LE(buf.length - 8, 4); \/\/ Uint32Array.BYTES_PER_ELEMENT   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442   return buf.buffer; }<\/code><\/pre>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f <code>id<\/code> \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a <code>Int32<\/code>-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u0432\u043e\u0435!), \u043d\u043e \u0438 \u043a\u0430\u043a \u044f\u0447\u0435\u0439\u043a\u0430 \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">const {shared} = workerData;  \/\/ [shared] = {lock:int32} + {size:uint32} + {data:uint8[]} const lock = new Int32Array(shared, 0, 1); const size = new Uint32Array(shared, Int32Array.BYTES_PER_ELEMENT, 1); const data = new Uint8Array(shared, Int32Array.BYTES_PER_ELEMENT + Uint32Array.BYTES_PER_ELEMENT); \/\/ ...   const id = lock[0];   const messageData = data.subarray(0, size[0]);<\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u0420\u0430\u0437\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0432\u044b\u0448\u0435 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0435\u0439 \u043e\u0431\u043c\u0435\u043d\u0430 \u044d\u0442\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<\/p>\n<figure class=\"full-width\"><figcaption>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0445\u0435\u043c\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c<\/figcaption><\/figure>\n<ol>\n<li>\n<p>\u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <code>message<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0435\u0433\u043e \u0432 <code>Coordinator<\/code>, \u0433\u0434\u0435 \u043e\u043d\u043e \u043f\u043e <strong>\u0430\u0432\u0442\u043e\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043d\u043e\u043c\u0443<\/strong> <code>id<\/code> \u0437\u0430\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 <code>Map<\/code>-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 <code>messages<\/code><\/p>\n<\/li>\n<li>\n<p>\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>dataFunc<\/code> \u043c\u044b \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 &#171;\u0441\u043a\u043b\u0435\u0438\u0432\u0430\u0435\u043c&#187; \u0438\u0445 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c <code>id<\/code> <strong>\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 <code>data<\/code>-\u0431\u0443\u0444\u0435\u0440 \u043c\u044b <strong>\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/strong> \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043f\u043e\u0442\u043e\u043a-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043b\u0438 \u043f\u0440\u043e\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u044c (\u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u0437\u0430\u043d\u044f\u0442\u044b), \u0438\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 <strong>\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c<\/strong> \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u043d\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <strong>\u043f\u0440\u044f\u043c\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439<\/strong> \u043f\u043e\u0442\u043e\u043a, &#8230;<\/p>\n<\/li>\n<li>\n<p>&#8230; \u0433\u0434\u0435 \u043e\u043d\u0438 \u043f\u043e <code>id<\/code> \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 <code>.emit<\/code><\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u041a\u043b\u0430\u0441\u0441 Coordinator<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class Coordinator extends Worker {   #messages = new Map(); \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439    #p32 = new Uint32Array(2);               \/\/ \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u0430\u043d\u043d\u044b\u0445 = [messageID, dataSize]   #p8  = new Uint8Array(this.#p32.buffer); \/\/ ... \u0438 \u0435\u0433\u043e uint8-\u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044f   #data = [this.#p8]; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u0447\u0430\u0441\u0442\u0435\u0439 \u0432 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u0431\u043b\u043e\u043a   #message2data;      \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432    #data2buffer() {     \/\/ \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0434\u0430\u043d\u043d\u044b\u0435     const buf = Buffer.concat(this.#data);     \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043b\u0438\u043d\u0443     buf.writeUInt32LE(buf.length - 8, 4); \/\/ Uint32Array.BYTES_PER_ELEMENT     \/\/ \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430     this.#data.length = 1;     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442     return buf.buffer;   };    constructor(filename, options) {     \/\/ \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b     const {port1, port2} = new MessageChannel();      \/* \u0434\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u043f\u0446\u0438\u0438       {         workerData : {           workerType : 'coordinator'         , port       : port2         }       , transferList : [port2]       }     *\/     ((options ??= {}).workerData ??= {}).workerType = 'coordinator';     ((options ??= {}).workerData ??= {}).port = port2;     ((options ??= {}).transferList ??= []).push(port2);     super(filename, options);      const {dataField, dataArray} = options;     this.#p32[0] = 0; \/\/ ID      this.#message2data = dataField       ? message => this.#data.push(dataField(message))       : message => this.#data.push(...dataArray(message));      const messages = this.#messages;     port1.on('message', ({threadId, port}) => {       \/\/ \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0438\u0439\u0441\u044f \u043f\u043e\u0440\u0442 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c       port.threadId = threadId;       this.emit('port.open', port);        port         .on('message', result => {           \/\/ \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e ID \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 ...           const message = messages.get(result.id);           if (message) {             messages.delete(result.id);             \/\/ ... \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c             this.emit('message', result, message);           }         })         .on('close', () => {           \/\/ \u043f\u0440\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u043f\u043e\u0440\u0442\u0430 - \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u043d\u0435\u0433\u043e           this.emit('port.close', port);           port.removeAllListeners();         });     });   }    \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u0442\u043e\u043a   postMessage(message) {     \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     this.#messages.set(this.#p32[0], message);     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0441\u043a\u043b\u0435\u0439\u043a\u0438 \u043e\u0434\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439     this.#message2data(message);     \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445     const buffer = this.#data2buffer();     \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \u0432 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435     super.postMessage(buffer, [buffer]);     \/\/ id = (id + 1) % 0x10000000     this.#p32[0]++;     this.#p32[0] &amp;= 0x0FFFFFFF;   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u0447\u0442\u043e \u0442\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c <code>Coordinator<\/code> \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u043c-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043f\u043e\u0434\u043d\u044f\u043b\u0438 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 <code>MessageChannel<\/code>, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043f\u0430\u0440\u044b \u043f\u043e\u0440\u0442\u043e\u0432, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u043e <a href=\"\/ru\/post\/689406\/\">\u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443 \u043f\u043e\u0442\u043e\u043a-<strong>\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u0440\u0442\u044b<\/strong> \u0434\u043b\u044f \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0445 \u0438\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e \u044d\u0442\u0438\u043c-\u0442\u043e \u043f\u043e\u0440\u0442\u0430\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442 \u043d\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u0432\u043e\u0435\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 <strong>\u043f\u0440\u044f\u043c\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><figcaption>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 MessageChannel<\/figcaption><\/figure>\n<h2>\u0420\u0430\u0437\u0443\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/h2>\n<p>\u0422\u0430\u043a, \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a &#8212; \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c. \u041d\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435?<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 <strong>\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0441\u0442\u043e\u0438\u0442 \u0443\u0436\u0435 \u0441\u0430\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0430<\/strong>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043e\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043a\u0430\u043a\u0443\u044e-\u0442\u043e &#171;\u0442\u044f\u0436\u0435\u043b\u0443\u044e&#187; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0432\u0440\u043e\u0434\u0435 \u043f\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u044d\u0448\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430, \u0442\u043e \u0435\u0433\u043e \u0441\u0442\u0430\u0440\u0442 \u043c\u043e\u0436\u0435\u0442 \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u044f\u0434\u0440\u043e CPU \u0434\u0430\u0436\u0435 <strong>\u043d\u0430 \u0432\u0441\u0435 100%<\/strong>.<\/p>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u044b\u0432\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a\u0438 \u0441\u0442\u043e\u0438\u0442 <strong>\u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c\/\u0443\u0431\u0438\u0432\u0430\u0442\u044c<\/strong> <strong>\u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0436\u0435<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f <strong>\u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\/\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435<\/strong> \u043f\u043e\u0442\u043e\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, <strong>\u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c<\/strong> \u0432\u0441\u0435\u0433\u0434\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c <strong>\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c CPU-\u044f\u0434\u0435\u0440<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437 \u0443\u0436 \u043c\u044b \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b\u0438 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430 \u043c\u043e\u0433\u0443\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u043a\u044d\u0448, \u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043b\u0438\u0448\u044c <strong>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/strong>, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0434\u043e\u043b\u044e<code>cache hit<\/code>.<\/p>\n<p>\u041a\u0430\u043a \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0448\u0435, \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0435\u0442 \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>WorkersPool<\/code>, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 <strong>\u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0442\u043e\u043a\u0430-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e.<\/p>\n<h2>\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 &#171;\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438&#187;<\/h2>\n<p>\u041d\u043e \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0443\u0436\u0435 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0432\u0441\u0435 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0438?<\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0440\u0430\u0431\u043e\u0442\u044b <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-339991","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/339991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=339991"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/339991\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=339991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=339991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=339991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}