{"id":371707,"date":"2024-05-21T04:55:01","date_gmt":"2024-05-21T04:55:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=371707"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=371707","title":{"rendered":"<span>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e Rust. \u0411\u043e\u043d\u0443\u0441<\/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-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/fj\/yi\/qn\/fjyiqnduv3l-rdgxnbu_t_qpgxk.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/fj\/yi\/qn\/fjyiqnduv3l-rdgxnbu_t_qpgxk.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>Hello world!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0431\u043e\u043d\u0443\u0441\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043f\u043e <a href=\"https:\/\/www.rust-lang.org\/ru\/\">Rust<\/a>.<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/790556\/\">\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/794941\/\">\u0412\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/796567\/\">\u0422\u0440\u0435\u0442\u044c\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/801201\/\">\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p><a href=\"https:\/\/my-js.org\/docs\/guide\/rust\/\">\u0414\u0440\u0443\u0433\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0432\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043d\u0430 <a href=\"https:\/\/google.github.io\/comprehensive-rust\/index.html\">Comprehensive Rust<\/a> \u2014 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e <code>Rust<\/code> \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>Android<\/code> \u0432 <code>Google<\/code> \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043d\u0430 \u043b\u044e\u0434\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u044e\u0442 \u043b\u044e\u0431\u044b\u043c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0415\u0449\u0435 \u0440\u0430\u0437: \u044d\u0442\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043d\u0430 \u0442\u0435\u0445, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043a\u043e\u0434\u0438\u0442\u044c ?<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u043c (concurrent) \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u043c (async) <code>Rust<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/doc.rust-lang.ru\/book\">\u041a\u043d\u0438\u0433\u0430\/\u0443\u0447\u0435\u0431\u043d\u0438\u043a \u043f\u043e Rust<\/a> (\u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435) \u2014 \u0433\u043b\u0430\u0432\u044b 16 \u0438 20<\/li>\n<li><a href=\"https:\/\/github.com\/rust-lang\/rustlings\">rustlings<\/a> \u2014 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 20<\/li>\n<li><a href=\"https:\/\/doc.rust-lang.ru\/stable\/rust-by-example\/\">Rust \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445<\/a> (\u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435) \u2014 \u043f\u0440\u0438\u043c\u0435\u0440\u044b 20.1 \u0438 20.2<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u043c. <a href=\"https:\/\/my-js.org\/docs\/cheatsheet\/rust\/\">\u0411\u043e\u043b\u044c\u0448\u0443\u044e \u0448\u043f\u0430\u0440\u0433\u0430\u043b\u043a\u0443 \u043f\u043e Rust<\/a>.<\/p>\n<p>  <\/p>\n<h1 id=\"parallelnyy-rust\">\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0439 <code>Rust<\/code><\/h1>\n<p>  <\/p>\n<p><code>Rust<\/code> \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c (concurrency) \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u041e\u0421 \u0441 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430\u043c\u0438 (mutexes) \u0438 \u043a\u0430\u043d\u0430\u043b\u0430\u043c\u0438 (channels).<\/p>\n<p>  <\/p>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0438\u043f\u043e\u0432 <code>Rust<\/code> \u0438\u0433\u0440\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u0443\u044e \u0440\u043e\u043b\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u0431\u0435\u0441\u0441\u0442\u0440\u0430\u0448\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u043e\u043c (fearless concurrency), \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<h2 id=\"potoki\">\u041f\u043e\u0442\u043e\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u0442\u043e\u043a\u0438 (threads) <code>Rust<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043f\u043e\u0442\u043e\u043a\u0430\u043c \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::thread; use std::time::Duration;  fn main() {     thread::spawn(|| {         for i in 1..10 {             println!(\"\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435: {i}!\");             thread::sleep(Duration::from_millis(5));         }     });      for i in 1..5 {         println!(\"\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435: {i}\");         thread::sleep(Duration::from_millis(5));     } }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u043f\u043e\u0442\u043e\u043a\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0434\u0435\u043c\u043e\u043d\u0430 (daemon threads), \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u0436\u0434\u0435\u0442 \u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/li>\n<li>\u043f\u043e\u0442\u043e\u043a\u0438 \u043f\u0430\u043d\u0438\u043a\u0443\u044e\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430<br \/> \n<ul>\n<li>\u043f\u0430\u043d\u0438\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 (payload), \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>downcast_ref<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u0436\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 (spawned) \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/li>\n<li>\u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>let handle = thread::spawn()<\/code> \u0438 \u0437\u0430\u0442\u0435\u043c <code>handle.join()<\/code><\/li>\n<li>\u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435 \u043f\u0430\u043d\u0438\u043a\u0443 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 <code>main<\/code><\/li>\n<li>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>Result<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0438\u0437 <code>handle.join()<\/code>, \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043f\u0430\u043d\u0438\u043a\u0438. \u0412 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c <a href=\"https:\/\/doc.rust-lang.org\/std\/any\/index.html\">Any<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041f\u043e\u0442\u043e\u043a\u0438 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::thread;  fn foo() {     let s = String::from(\"\u043f\u0440\u0438\u0432\u0435\u0442\");     thread::spawn(|| {         println!(\"\u0434\u043b\u0438\u043d\u0430: {}\", s.len());     }); }  fn main() {     foo(); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/doc.rust-lang.org\/std\/thread\/fn.scope.html\">scoped threads<\/a> (\u043f\u043e\u0442\u043e\u043a\u0438 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438):<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::thread;  fn main() {     let s = String::from(\"\u043f\u0440\u0438\u0432\u0435\u0442\");      thread::scope(|scope| {         scope.spawn(|| {             println!(\"\u0434\u043b\u0438\u043d\u0430: {}\", s.len());         });     }); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043a\u043e\u0433\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>thread::scope<\/code> \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f, \u0432\u0441\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435<\/li>\n<li>\u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f <code>Rust<\/code>: \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0438\u043b\u0438 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"kanaly\">\u041a\u0430\u043d\u0430\u043b\u044b<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043d\u0430\u043b\u044b (channels) <code>Rust<\/code> \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439: <code>Sender&lt;T><\/code> (\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c\/\u043f\u0435\u0440\u0435\u0434\u0430\u0442\u0447\u0438\u043a) \u0438 <code>Receiver&lt;T><\/code> (\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c\/\u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a). \u041e\u043d\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u043d\u0430\u043b\u0430, \u043d\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::mpsc;  fn main() {     let (tx, rx) = mpsc::channel();      tx.send(10).unwrap();     tx.send(20).unwrap();      println!(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e: {:?}\", rx.recv());     println!(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e: {:?}\", rx.recv());      let tx2 = tx.clone();     tx2.send(30).unwrap();     println!(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e: {:?}\", rx.recv()); }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><code>mpsc<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 Multi-Producer, Single-Consumer (\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439, \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c). <code>Sender<\/code> \u0438 <code>SyncSender<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 <code>Clone<\/code> (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439), \u0430 <code>Receiver<\/code> \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043d\u0430\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c)<\/li>\n<li><code>send()<\/code> \u0438 <code>recv()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 <code>Result<\/code>. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 <code>Err<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>Sender<\/code> \u0438\u043b\u0438 <code>Receiver<\/code> \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d (dropped) \u0438 \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0442<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b<\/strong><\/p>\n<p>  <\/p>\n<p><code>mpsc::channel()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 (unbounded) \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::mpsc; use std::thread; use std::time::Duration;  fn main() {     let (tx, rx) = mpsc::channel();      thread::spawn(move || {         let thread_id = thread::current().id();         for i in 1..10 {             tx.send(format!(\"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 {i}\")).unwrap();             println!(\"{thread_id:?}: \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 {i}\");         }         println!(\"{thread_id:?}: \u0433\u043e\u0442\u043e\u0432\u043e\");     });     thread::sleep(Duration::from_millis(100));      for msg in rx.iter() {         println!(\"\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a: \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e {msg}\");     } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b<\/strong><\/p>\n<p>  <\/p>\n<p><code>send()<\/code> \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e (bounded) \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::mpsc; use std::thread; use std::time::Duration;  fn main() {     let (tx, rx) = mpsc::sync_channel(3);      thread::spawn(move || {         let thread_id = thread::current().id();         for i in 1..10 {             tx.send(format!(\"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 {i}\")).unwrap();             println!(\"{thread_id:?}: \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 {i}\");         }         println!(\"{thread_id:?}: \u0433\u043e\u0442\u043e\u0432\u043e\");     });     thread::sleep(Duration::from_millis(100));      for msg in rx.iter() {         println!(\"\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a: \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e {msg}\");     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b\u0437\u043e\u0432 <code>send()<\/code> \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432 \u043a\u0430\u043d\u0430\u043b\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041f\u043e\u0442\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u0441\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c<\/li>\n<li>\u0432\u044b\u0437\u043e\u0432 <code>send()<\/code> \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u043e\u0439 (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f <code>Result<\/code>), \u0435\u0441\u043b\u0438 \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0442. \u041a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f<\/li>\n<li>\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0441 \u043d\u0443\u043b\u0435\u0432\u044b\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;rendezvous channel&#187;. \u041a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>send()<\/code> \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a, \u043f\u043e\u043a\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 <code>read()<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"send-i-sync\">Send \u0438 Sync<\/h2>\n<p>  <\/p>\n<p>\u041e\u0442\u043a\u0443\u0434\u0430 <code>Rust<\/code> \u0437\u043d\u0430\u0435\u0442 \u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u0435\u0442\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u0431\u0449\u0435\u043c\u0443 (shared) \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432? \u041e\u0442\u0432\u0435\u0442 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 \u0434\u0432\u0443\u0445 \u0442\u0440\u0435\u0439\u0442\u0430\u0445:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/marker\/trait.Send.html\">Send<\/a>: \u0442\u0438\u043f <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Send<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 <code>T<\/code> \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439<\/li>\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/marker\/trait.Sync.html\">Sync<\/a>: \u0442\u0438\u043f <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Sync<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 <code>&amp;T<\/code> \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439<\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>Send<\/code> \u0438 <code>Sync<\/code> \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <a href=\"https:\/\/google.github.io\/comprehensive-rust\/unsafe\/unsafe-traits.html\">\u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438 \u0442\u0440\u0435\u0439\u0442\u0430\u043c\u0438<\/a>. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u0445 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u044b <code>Send<\/code> \u0438 <code>Sync<\/code>. \u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b \u0432 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0438\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043e \u0442\u0438\u043f\u0430\u0445 <code>Send<\/code> \u0438 <code>Sync<\/code> \u043c\u043e\u0436\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u0445 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0442\u0438\u043f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0445 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432 (thread-safety) \u0441\u0432\u043e\u0439\u0441\u0442\u0432<\/li>\n<li>\u044d\u0442\u0438 \u0442\u0438\u043f\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u0449\u0438\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0442\u0440\u0435\u0439\u0442\u0430\u043c\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>Send<\/strong><\/p>\n<p>  <\/p>\n<p>\u0422\u0438\u043f <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Send<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>T<\/code> \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439.<\/p>\n<p>  <\/p>\n<p>\u042d\u0444\u0444\u0435\u043a\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b <code>T<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u043d\u043e\u0432\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u043f\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a <code>SQLite<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435.<\/p>\n<p>  <\/p>\n<p><strong>Sync<\/strong><\/p>\n<p>  <\/p>\n<p>\u0422\u0438\u043f <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Sync<\/code>, \u0435\u0441\u043b\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e <code>T<\/code> \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u044b\u043c, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0433\u043b\u0430\u0441\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Sync<\/code>, \u0435\u0441\u043b\u0438 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 <code>&amp;T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Send<\/code>.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c&#187; (thread-safe) \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u0441\u044b\u043b\u043e\u043a \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Sync<\/code>, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u0431\u0435\u0437 \u0440\u0438\u0441\u043a\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u0433\u043e\u043d\u043e\u043a \u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 (data race) \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0442\u0438\u043f \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0430\u043d\u043d\u044b\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0430 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f, \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/strong><\/p>\n<p>  <\/p>\n<p><em>Send + Sync<\/em><\/p>\n<p>  <\/p>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>Send + Sync<\/code>:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>i8<\/code>, <code>f32<\/code>, <code>bool<\/code>, <code>char<\/code>, <code>&amp;str<\/code> etc.<\/li>\n<li><code>(T1, T2)<\/code>, <code>[T; N]<\/code>, <code>&amp;[T]<\/code>, <code>struct { x: T }<\/code> etc.<\/li>\n<li><code>String<\/code>, <code>Option&lt;T><\/code>, <code>Vec&lt;T><\/code>, <code>Box&lt;T><\/code> etc.<\/li>\n<li><code>Arc&lt;T><\/code> \u2014 \u044f\u0432\u043d\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u043c\u0443 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0443 \u0441\u0441\u044b\u043b\u043e\u043a<\/li>\n<li><code>Mutex&lt;T><\/code> \u2014 \u044f\u0432\u043d\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435<\/li>\n<li><code>AtomicBool<\/code>, <code>AtomicU8<\/code> etc., \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>Send + Sync<\/code>, \u043a\u043e\u0433\u0434\u0430 \u0442\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><em>Send + !Sync<\/em><\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438, \u043d\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0438\u0445 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u044c\u044e:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>mpsc::Sender&lt;T><\/code><\/li>\n<li><code>mpsc::Receiver&lt;T><\/code><\/li>\n<li><code>Cell&lt;T><\/code><\/li>\n<li><code>RefCell&lt;T><\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><em>!Send + Sync<\/em><\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438, \u043d\u043e \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>MutexGuard&lt;T: Sync><\/code> \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u0443\u0440\u043e\u0432\u043d\u044f \u041e\u0421, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u044b \u0432 \u0441\u043e\u0437\u0434\u0430\u0432\u0448\u0435\u043c \u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<p><em>!Send + !Sync<\/em><\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438 \u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Rc&lt;T><\/code> \u2014 \u043a\u0430\u0436\u0434\u044b\u0439 <code>Rc&lt;T><\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <code>RcBox&lt;T><\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0439 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0441\u0441\u044b\u043b\u043e\u043a<\/li>\n<li><code>*const T<\/code>, <code>*mut T<\/code> \u2014 <code>Rust<\/code> \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u044b\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0438\u0445 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"obschee-sostoyanie\">\u041e\u0431\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p><code>Rust<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u0449\u0438\u0445 (shared) \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0432\u0443\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/struct.Arc.html\"><code>Arc \u2014 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0439 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 T<\/code>: \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 <code>T<\/code> \u043f\u0440\u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043d\u0435\u0435<\/a><br \/>  <a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/struct.Mutex.html\"><code>Mutex \u2014 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e T<\/code><\/a>\n<p><strong>Arc<\/strong><\/p>\n<p>  <\/p>\n<p><code>Arc&lt;T><\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a <code>T<\/code> \u0447\u0435\u0440\u0435\u0437 <code>Arc::clone()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::Arc; use std::thread;  fn main() {     let v = Arc::new(vec![10, 20, 30]);     let mut handles = Vec::new();     for _ in 1..5 {         let v = Arc::clone(&amp;v);         handles.push(thread::spawn(move || {             let thread_id = thread::current().id();             println!(\"{thread_id:?}: {v:?}\");         }));     }      handles.into_iter().for_each(|h| h.join().unwrap());     println!(\"v: {v:?}\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Arc<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 Atomic Reference Counter (\u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0439 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0441\u0441\u044b\u043b\u043e\u043a) \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 <code>Rc<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/li>\n<li><code>Arc&lt;T><\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Clone<\/code> \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u0434\u0435\u043b\u0430\u0435\u0442 \u043b\u0438 \u044d\u0442\u043e <code>T<\/code>. \u041e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Send<\/code> \u0438 <code>Sync<\/code>, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 <code>T<\/code> \u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442<\/li>\n<li><code>Arc::clone()<\/code> \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0446\u0435\u043d\u0443 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>T<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u043c<\/li>\n<li>\u043e\u0441\u0442\u0435\u0440\u0435\u0433\u0430\u0439\u0442\u0435\u0441\u044c \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432, <code>Arc<\/code> \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 \u0434\u043b\u044f \u0438\u0445 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f<br \/> \n<ul>\n<li>\u0432 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c <code>std::sync::Weak<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>Mutex<\/strong><\/p>\n<p>  <\/p>\n<p><code>Mutex&lt;T><\/code> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a <code>T<\/code> \u0447\u0435\u0440\u0435\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (\u0444\u043e\u0440\u043c\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u0438):<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::Mutex;  fn main() {     let v = Mutex::new(vec![10, 20, 30]);     println!(\"v: {:?}\", v.lock().unwrap());      {         let mut guard = v.lock().unwrap();         guard.push(40);     }      println!(\"v: {:?}\", v.lock().unwrap()); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u044f\u0432\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e (<code>impl&lt;T: Send> Sync for Mutex&lt;T><\/code>)<a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/struct.Mutex.html#impl-Sync-for-Mutex%3CT%3E\">https:\/\/doc.rust-lang.org\/std\/sync\/struct.Mutex.html#impl-Sync-for-Mutex%3CT%3E<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Mutex<\/code> \u0432 <code>Rust<\/code> \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u2014 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<br \/> \n<ul>\n<li>\u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c (acquire) \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u043f\u0435\u0440\u0435\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c<\/li>\n<\/ul>\n<\/li>\n<li>\u0438\u0437 <code>&amp;Mutex&lt;T><\/code> \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 (lock) \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>&amp;mut T<\/code>. <code>MutexGuard<\/code> \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e <code>&amp;mut T<\/code> \u043d\u0435 \u0436\u0438\u0432\u0435\u0442 \u0434\u043e\u043b\u044c\u0448\u0435 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439 (held) \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438<\/li>\n<li><code>Mutex&lt;T><\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Send<\/code> \u0438 <code>Sync<\/code>, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 <code>T<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Send<\/code><\/li>\n<li><code>RwLock<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u0430\u043a \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438<\/li>\n<li>\u043f\u043e\u0447\u0435\u043c\u0443 <code>lock()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Result<\/code>?<br \/> \n<ul>\n<li>\u0415\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043c\u044c\u044e\u0442\u0435\u043a\u0441, \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u0442, \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f &#171;\u043e\u0442\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c&#187; (poisoned), \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043d\u0435\u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0412\u044b\u0437\u043e\u0432 <code>lock()<\/code> \u043d\u0430 \u043e\u0442\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 <a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/struct.PoisonError.html\">PoisonError<\/a>. \u0414\u043b\u044f \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>into_iter()<\/code> \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0435<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <code>Arc<\/code> \u0438 <code>Mutex<\/code> \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::thread; \/\/ use std::sync::{Arc, Mutex};  fn main() {     let v = vec![10, 20, 30];     let handle = thread::spawn(|| {         v.push(10);     });     v.push(1000);      handle.join().unwrap();     println!(\"v: {v:?}\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::{Arc, Mutex}; use std::thread;  fn main() {     let v = Arc::new(Mutex::new(vec![10, 20, 30]));      let v2 = Arc::clone(&amp;v);     let handle = thread::spawn(move || {         let mut v2 = v2.lock().unwrap();         v2.push(10);     });      {         let mut v = v.lock().unwrap();         v.push(1000);     }      handle.join().unwrap();      println!(\"v: {v:?}\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>v<\/code> \u043e\u0431\u0435\u0440\u043d\u0443\u0442 \u0432 <code>Arc<\/code> \u0438 <code>Mutex<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0445 \u0437\u043e\u043d\u044b \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043e\u0440\u0442\u043e\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u044b<br \/> \n<ul>\n<li>\u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 <code>Mutex<\/code> \u0432 <code>Arc<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u043c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438<\/li>\n<\/ul>\n<\/li>\n<li><code>v: Arc&lt;_><\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u0430\u043a <code>v2<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <code>move<\/code> \u0432 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435 \u043b\u044f\u043c\u0431\u0434\u044b<\/li>\n<li>\u0431\u043b\u043e\u043a\u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0434\u043b\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0443\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 <code>LockGuard<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"uprazhneniya\">\u0423\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u0435\u043c\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u043d\u0430 \u0434\u0432\u0443\u0445 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f\u0445:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%B1%D0%B5%D0%B4%D0%B0%D1%8E%D1%89%D0%B8%D1%85_%D1%84%D0%B8%D0%BB%D0%BE%D1%81%D0%BE%D1%84%D0%B0%D1%85\">\u043e\u0431\u0435\u0434\u0430\u044e\u0449\u0438\u0435 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u044b<\/a> \u2014 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430<\/li>\n<li>\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0441\u044b\u043b\u043e\u043a<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u0435\u0434\u0430\u044e\u0449\u0438\u0435 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<p>  <\/p>\n<p>\u041f\u044f\u0442\u044c \u0431\u0435\u0437\u043c\u043e\u043b\u0432\u043d\u044b\u0445 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432 \u0441\u0438\u0434\u044f\u0442 \u0432\u043e\u043a\u0440\u0443\u0433 \u043a\u0440\u0443\u0433\u043b\u043e\u0433\u043e \u0441\u0442\u043e\u043b\u0430, \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u043c \u0441\u0442\u043e\u0438\u0442 \u0442\u0430\u0440\u0435\u043b\u043a\u0430 \u0441\u043f\u0430\u0433\u0435\u0442\u0442\u0438. \u041d\u0430 \u0441\u0442\u043e\u043b\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u043e\u0439 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432 \u043b\u0435\u0436\u0438\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0432\u0438\u043b\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u043c\u043e\u0436\u0435\u0442 \u043b\u0438\u0431\u043e \u0435\u0441\u0442\u044c, \u043b\u0438\u0431\u043e \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u044f\u0442\u044c. \u041f\u0440\u0438\u0435\u043c \u043f\u0438\u0449\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0441\u043f\u0430\u0433\u0435\u0442\u0442\u0438 \u2014 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0430\u0441. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u043c\u043e\u0436\u0435\u0442 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0432\u0435 \u0432\u0438\u043b\u043a\u0438 \u2014 \u0432\u0437\u044f\u0442\u0443\u044e \u0441\u043f\u0440\u0430\u0432\u0430 \u0438 \u0441\u043b\u0435\u0432\u0430.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0443\u044e \u0432\u0438\u043b\u043a\u0443 (\u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430) \u0438\u043b\u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u2014 \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u0436\u0435 \u0434\u0435\u0440\u0436\u0438\u0442 \u0435\u0435. \u0412\u0437\u044f\u0442\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0438\u043b\u043a\u0438 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0435\u0435 \u043d\u0430 \u0441\u0442\u043e\u043b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c (\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c), \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u043b\u043e\u0434\u0430\u0442\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0447\u0435\u0440\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0435\u043c \u043f\u0438\u0449\u0438 \u0438 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f 100 \u0440\u0430\u0437.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::{mpsc, Arc, Mutex}; use std::thread; use std::time::Duration;  struct Fork;  struct Philosopher {     name: String,     \/\/ left_fork: ...     \/\/ right_fork: ...     \/\/ thoughts: ... }  impl Philosopher {     fn think(&amp;self) {         self.thoughts             .send(format!(\"\u042d\u0432\u0440\u0438\u043a\u0430! {} \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b(\u0430) \u043d\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e!\", &amp;self.name))             .unwrap();     }      fn eat(&amp;self) {         \/\/ \u0411\u0435\u0440\u0435\u043c \u0432\u0438\u043b\u043a\u0438         println!(\"{} \u0435\u0441\u0442...\", &amp;self.name);         thread::sleep(Duration::from_millis(10));     } }  static PHILOSOPHERS: &amp;[&amp;str] =     &amp;[\"\u0421\u043e\u043a\u0440\u0430\u0442\", \"\u0413\u0438\u043f\u0430\u0442\u0438\u044f\", \"\u041f\u043b\u0430\u0442\u043e\u043d\", \"\u0410\u0440\u0438\u0441\u0442\u043e\u0442\u0435\u043b\u044c\", \"\u041f\u0438\u0444\u0430\u0433\u043e\u0440\"];  fn main() {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0438\u043b\u043a\u0438      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432      \/\/ \u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u044f\u0435\u0442 \u0438 \u0435\u0441\u0442 100 \u0440\u0430\u0437      \/\/ \u0412\u044b\u0432\u043e\u0434\u0438\u043c \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <a href=\"https:\/\/doc.rust-lang.org\/std\/mem\/fn.swap.html\">std::mem::swap<\/a> \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432\u0437\u0430\u0438\u043c\u043d\u043e\u0439 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 (deadlock).<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"rust\">use std::sync::{mpsc, Arc, Mutex}; use std::thread; use std::time::Duration;  struct Fork;  struct Philosopher {     name: String,     left_fork: Arc&lt;Mutex&lt;Fork>>,     right_fork: Arc&lt;Mutex&lt;Fork>>,     thoughts: mpsc::SyncSender&lt;String>, }  impl Philosopher {     fn think(&amp;self) {         self.thoughts             .send(format!(\"\u042d\u0432\u0440\u0438\u043a\u0430! {} \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b(\u0430) \u043d\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e!\", &amp;self.name))             .unwrap();     }      fn eat(&amp;self) {         println!(\"{} \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0435\u0441\u0442\u044c\", &amp;self.name);          let _left = self.left_fork.lock().unwrap();         let _right = self.right_fork.lock().unwrap();          println!(\"{} \u0435\u0441\u0442...\", &amp;self.name);          thread::sleep(Duration::from_millis(10));     } }  static PHILOSOPHERS: &amp;[&amp;str] =     &amp;[\"\u0421\u043e\u043a\u0440\u0430\u0442\", \"\u0413\u0438\u043f\u0430\u0442\u0438\u044f\", \"\u041f\u043b\u0430\u0442\u043e\u043d\", \"\u0410\u0440\u0438\u0441\u0442\u043e\u0442\u0435\u043b\u044c\", \"\u041f\u0438\u0444\u0430\u0433\u043e\u0440\"];  fn main() {     let (tx, rx) = mpsc::sync_channel(10);      let forks = (0..PHILOSOPHERS.len())         .map(|_| Arc::new(Mutex::new(Fork)))         .collect::&lt;Vec&lt;_>>();      for i in 0..forks.len() {         let tx = tx.clone();          let mut left_fork = Arc::clone(&amp;forks[i]);         let mut right_fork = Arc::clone(&amp;forks[(i + 1) % forks.len()]);          \/\/ \u0412\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u0432\u0437\u0430\u0438\u043c\u043d\u043e\u0439 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0433\u0434\u0435-\u0442\u043e \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u044c \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u044e.         \/\/ \u041c\u0435\u043d\u044f\u0435\u043c \u0432\u0438\u043b\u043a\u0438 \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u0431\u0435\u0437 \u0438\u0445 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438         if i == forks.len() - 1 {             std::mem::swap(&amp;mut left_fork, &amp;mut right_fork);         }          let philosopher = Philosopher {             name: PHILOSOPHERS[i].to_string(),             thoughts: tx,             left_fork,             right_fork,         };          thread::spawn(move || {             for _ in 0..100 {                 philosopher.eat();                 philosopher.think();             }         });     }      drop(tx);      for thought in rx {         println!(\"{thought}\");     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><strong>\u041c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0441\u044b\u043b\u043e\u043a<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0441\u044b\u043b\u043e\u043a. \u041e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u043d\u0435\u0439. \u0417\u0430\u0442\u0435\u043c \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u0442\u043e\u043c \u0436\u0435 \u0434\u043e\u043c\u0435\u043d\u0435 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u044b.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043a\u043b\u0438\u0435\u043d\u0442 <code>HTTP<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/docs.rs\/reqwest\/\">reqwest<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cargo add reqwest --features blocking,rustls-tls<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/docs.rs\/scraper\/\">scraper<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cargo add scraper<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/docs.rs\/thiserror\/\">thiserror<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cargo add thiserror<\/code><\/pre>\n<p>  <\/p>\n<p><code>Cargo.toml<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">[package] name = \"link-checker\" version = \"0.1.0\" edition = \"2021\" publish = false  [dependencies] reqwest = { version = \"0.11.12\", features = [\"blocking\", \"rustls-tls\"] } scraper = \"0.13.0\" thiserror = \"1.0.37\"<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u0430, \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u0430\u043a <code>https:\/\/www.google.org<\/code>.<\/p>\n<p>  <\/p>\n<p><code>src\/main.rs<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use reqwest::blocking::Client; use reqwest::Url; use scraper::{Html, Selector}; use thiserror::Error;  #[derive(Error, Debug)] enum Error {     #[error(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430: {0}\")]     ReqwestError(#[from] reqwest::Error),     #[error(\"\u043f\u043b\u043e\u0445\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 HTTP: {0}\")]     BadResponse(String), }  #[derive(Debug)] struct CrawlCommand {     url: Url,     extract_links: bool, }  fn visit_page(client: &amp;Client, command: &amp;CrawlCommand) -> Result&lt;Vec&lt;Url>, Error> {     println!(\"\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 {:#}\", command.url);      let response = client.get(command.url.clone()).send()?;      if !response.status().is_success() {         return Err(Error::BadResponse(response.status().to_string()));     }      let mut link_urls = Vec::new();      if !command.extract_links {         return Ok(link_urls);     }      let base_url = response.url().to_owned();     let body_text = response.text()?;     let document = Html::parse_document(&amp;body_text);      let selector = Selector::parse(\"a\").unwrap();     let href_values = document         .select(&amp;selector)         .filter_map(|element| element.value().attr(\"href\"));     for href in href_values {         match base_url.join(href) {             Ok(link_url) => {                 link_urls.push(link_url);             }             Err(err) => {                 println!(\"\u0432 {base_url:#} \u043d\u0435 \u043f\u043e\u0434\u0434\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0443 {href:?}: {err}\");             }         }     }     Ok(link_urls) }  fn main() {     let client = Client::new();     let start_url = Url::parse(\"https:\/\/www.google.org\").unwrap();     let crawl_command = CrawlCommand{ url: start_url, extract_links: true };      match visit_page(&amp;client, &amp;crawl_command) {         Ok(links) => println!(\"\u0441\u0441\u044b\u043b\u043a\u0438: {links:#?}\"),         Err(err) => println!(\"\u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0441\u0441\u044b\u043b\u043a\u0438: {err:#}\"),     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0441\u044b\u043b\u043e\u043a: \u043e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c\u044b\u0435 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0432 \u043a\u0430\u043d\u0430\u043b \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044c\u0442\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e<\/li>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0439\u0442\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0435 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u0441\u044b\u043b\u043e\u043a \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0434\u043e\u043c\u0435\u043d\u0430 <code>www.google.org<\/code>. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u043f\u0440\u0435\u0434\u0435\u043b \u0432 100 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438\u043b\u0438 \u043e\u043a\u043e\u043b\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0430\u0439\u0442 \u0432\u0430\u0441 \u043d\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043b<\/li>\n<\/ul>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"rust\">use std::sync::{mpsc, Arc, Mutex}; use std::thread; use std::collections::HashSet;  use reqwest::blocking::Client; use reqwest::Url; use scraper::{Html, Selector}; use thiserror::Error;  #[derive(Error, Debug)] enum Error {     #[error(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430: {0}\")]     ReqwestError(#[from] reqwest::Error),     #[error(\"\u043f\u043b\u043e\u0445\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 HTTP: {0}\")]     BadResponse(String), }  #[derive(Debug)] struct CrawlCommand {     url: Url,     extract_links: bool, }  fn visit_page(client: &amp;Client, command: &amp;CrawlCommand) -> Result&lt;Vec&lt;Url>, Error> {     println!(\"\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 {:#}\", command.url);      let response = client.get(command.url.clone()).send()?;      if !response.status().is_success() {         return Err(Error::BadResponse(response.status().to_string()));     }      let mut link_urls = Vec::new();      if !command.extract_links {         return Ok(link_urls);     }      let base_url = response.url().to_owned();     let body_text = response.text()?;     let document = Html::parse_document(&amp;body_text);      let selector = Selector::parse(\"a\").unwrap();     let href_values = document         .select(&amp;selector)         .filter_map(|element| element.value().attr(\"href\"));     for href in href_values {         match base_url.join(href) {             Ok(link_url) => {                 link_urls.push(link_url);             }             Err(err) => {                 println!(\"\u0432 {base_url:#} \u043d\u0435 \u043f\u043e\u0434\u0434\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0443 {href:?}: {err}\");             }         }     }     Ok(link_urls) }  struct CrawlState {     domain: String,     visited_pages: HashSet&lt;String>, }  impl CrawlState {     fn new(start_url: &amp;Url) -> CrawlState {         let mut visited_pages = HashSet::new();          visited_pages.insert(start_url.as_str().to_string());          CrawlState {             domain: start_url.domain().unwrap().to_string(),             visited_pages         }     }      \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0434\u043e\u043b\u0436\u043d\u044b \u043b\u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435     fn should_extract_links(&amp;self, url: &amp;Url) -> bool {         let Some(url_domain) = url.domain() else {             return false;         };         url_domain == self.domain     }      \/\/\/ \u041f\u043e\u043c\u0435\u0447\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u0430\u043a \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u043d\u0443\u044e,     \/\/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 `false`, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0443\u0436\u0435 \u043f\u043e\u0441\u0435\u0449\u0430\u043b\u0430\u0441\u044c     fn mark_visited(&amp;mut self, url: &amp;Url) -> bool {         self.visited_pages.insert(url.as_str().to_string())     } }  type CrawlResult = Result&lt;Vec&lt;Url>, (Url, Error)>;  fn spawn_crawler_threads(     command_receiver: mpsc::Receiver&lt;CrawlCommand>,     result_sender: mpsc::Sender&lt;CrawlResult>,     thread_count: u32, ) {     let command_receiver = Arc::new(Mutex::new(command_receiver));      for _ in 0..thread_count {         let result_sender = result_sender.clone();         let command_receiver = command_receiver.clone();          thread::spawn(move || {             let client = Client::new();              loop {                 let command_result = {                     let receiver_guard = command_receiver.lock().unwrap();                     receiver_guard.recv()                 };                  let Ok(crawl_command) = command_result else {                     \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d, \u043a\u043e\u043c\u0430\u043d\u0434 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442                     break;                 };                  let crawl_result = match visit_page(&amp;client, &amp;crawl_command) {                     Ok(link_urls) => Ok(link_urls),                     Err(error) => Err((crawl_command.url, error)),                 };                  result_sender.send(crawl_result).unwrap();             }         });     } }  fn control_crawl(     start_url: Url,     command_sender: mpsc::Sender&lt;CrawlCommand>,     result_receiver: mpsc::Receiver&lt;CrawlResult>, ) -> Vec&lt;Url> {     let mut crawl_state = CrawlState::new(&amp;start_url);      let start_command = CrawlCommand { url: start_url, extract_links: true };     command_sender.send(start_command).unwrap();      let mut pending_urls = 1;      let mut bad_urls = Vec::new();      while pending_urls > 0 {         let crawl_result = result_receiver.recv().unwrap();         pending_urls -= 1;          match crawl_result {             Ok(link_urls) => {                 for url in link_urls {                     if crawl_state.mark_visited(&amp;url) {                         let extract_links = crawl_state.should_extract_links(&amp;url);                         let crawl_command = CrawlCommand { url, extract_links };                         command_sender.send(crawl_command).unwrap();                         pending_urls += 1;                     }                 }             }             Err((url, error)) => {                 bad_urls.push(url);                 println!(\"\u043f\u0440\u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0438 \u0441\u0441\u044b\u043b\u043e\u043a \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430: {:#}\", error);                 continue;             }         }     }     bad_urls }  fn check_links(start_url: Url) -> Vec&lt;Url> {     let (result_sender, result_receiver) = mpsc::channel::&lt;CrawlResult>();     let (command_sender, command_receiver) = mpsc::channel::&lt;CrawlCommand>();     spawn_crawler_threads(command_receiver, result_sender, 16);     control_crawl(start_url, command_sender, result_receiver) }  fn main() {     let start_url = reqwest::Url::parse(\"https:\/\/www.google.org\").unwrap();     let bad_urls = check_links(start_url);     println!(\"\u043f\u043b\u043e\u0445\u0438\u0435 URL: {:#?}\", bad_urls); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h1 id=\"asinhronnyy-rust\">\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 Rust<\/h1>\n<p>  <\/p>\n<p>&#171;\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c&#187; (async) \u2014 \u044d\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u041a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0438\u043b\u0438 \u043d\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f (\u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e) \u0437\u0430\u0434\u0430\u0447\u0430 \u0438 \u0442.\u0434. \u0422\u0430\u043a\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0434\u0430\u0447 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043d\u0438\u0437\u043a\u0438\u0435, \u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u0434\u043b\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>Rust<\/code> \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0444\u044c\u044e\u0447\u0435\u0440\u0430\u0445 (futures, \u043e\u0442 &#171;future&#187; \u2014 \u0431\u0443\u0434\u0443\u0449\u0435\u0435), \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u0424\u044c\u044e\u0447\u0435\u0440\u044b &#171;\u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442\u0441\u044f&#187; (polled) \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0442 \u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440\u044b \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (async runtime). \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u0441\u0440\u0435\u0434. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/tokio.rs\/\">Tokio<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432 <code>Python<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0445\u043e\u0436\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0432 <code>asyncio<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0433\u043e \u0442\u0438\u043f <code>Future<\/code> \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 (callbacks), \u0430 \u043d\u0435 \u043d\u0430 \u043e\u043f\u0440\u043e\u0441\u0430\u0445. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b <code>Python<\/code> \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0446\u0438\u043a\u043b\u0435, \u043a\u0430\u043a \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b <code>Rust<\/code><\/li>\n<li><code>Promise<\/code> \u0432 <code>JavaScript<\/code> \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0444\u044c\u044e\u0447\u0435\u0440, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043a\u043e\u043b\u0431\u044d\u043a\u0430\u0445. \u0421\u0440\u0435\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0446\u0438\u043a\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (event loop), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043c\u0438\u0441\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043a\u0440\u044b\u0442\u044b\u043c\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"osnovy-asinhronnosti\">\u041e\u0441\u043d\u043e\u0432\u044b \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438<\/h2>\n<p>  <\/p>\n<p><strong>async\/await<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 <code>Rust<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use futures::executor::block_on;  async fn count_to(count: i32) {     for i in 1..=count {         println!(\"\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430: {i}!\");     } }  async fn async_main(count: i32) {     count_to(count).await; }  fn main() {     block_on(async_main(10)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u044d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430. \u0412 \u043d\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u043e\u043b\u0433\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c<\/li>\n<li>\u043a\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f?<br \/> \n<ul>\n<li>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>let future: () = async_main(10);<\/code> \u0432 <code>main()<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435<\/li>\n<\/ul>\n<\/li>\n<li>\u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>async<\/code> \u2014 \u044d\u0442\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0430\u0445\u0430\u0440. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u043c<\/li>\n<li>\u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code> \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440<\/li>\n<li>\u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c (executor). <code>block_on()<\/code> \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u0430<\/li>\n<li><code>.await<\/code> \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0436\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>block_on()<\/code>, <code>await<\/code> \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a<\/li>\n<li><code>await<\/code> \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0438\u043b\u0438 \u0431\u043b\u043e\u043a\u0430, \u043e \u0447\u0435\u043c \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435)<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0424\u044c\u044e\u0447\u0435\u0440\u044b<\/strong><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/doc.rust-lang.org\/std\/future\/trait.Future.html\">Future<\/a> \u2014 \u044d\u0442\u043e \u0442\u0440\u0435\u0439\u0442, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u0424\u044c\u044e\u0447\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f, <code>poll()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <a href=\"https:\/\/doc.rust-lang.org\/std\/task\/enum.Poll.html\">Poll<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::pin::Pin; use std::task::Context;  pub trait Future {     type Output;      fn poll(self: Pin&lt;&amp;mut Self>, cx: &amp;mut Context&lt;'_>) -> Poll&lt;Self::Output>; }  pub enum Poll&lt;T> {     Ready(T),     Pending, }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>impl Future<\/code>. \u0422\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e (\u043d\u043e \u0440\u0435\u0434\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f) \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>Future<\/code> \u0434\u043b\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>JoinHandle<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 <code>tokio::spawn<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Future<\/code>, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u0441\u044f (join) \u043a \u043d\u0435\u043c\u0443.<\/p>\n<p>  <\/p>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>await<\/code> \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u043a\u0430 \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0442\u0438\u043f\u044b <code>Future<\/code> \u0438 <code>Poll<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e<\/li>\n<li>\u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c <code>Pin<\/code> \u0438 <code>Context<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b. \u041a\u043e\u0440\u043e\u0442\u043a\u043e:<br \/> \n<ul>\n<li><code>Context<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0444\u044c\u044e\u0447\u0435\u0440\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043e\u043f\u0440\u043e\u0441 \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/li>\n<li><code>Pin<\/code> \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0444\u044c\u044e\u0447\u0435\u0440 \u043d\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0441\u044b\u043b\u043a\u0438 \u0432 \u044d\u0442\u043e\u043c \u0444\u044c\u044e\u0447\u0435\u0440\u0435 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0441\u044b\u043b\u043a\u0438 \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 <code>await<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0421\u0440\u0435\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u0440\u0435\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (runtime) \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (reactor) \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432 (executor). <code>Rust<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 &#171;\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439&#187; \u0441\u0440\u0435\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/tokio.rs\/\">Tokio<\/a> \u2014 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439, \u0441 \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <a href=\"https:\/\/hyper.rs\/\">Hyper<\/a> \u0434\u043b\u044f <code>HTTP<\/code> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/hyperium\/tonic\">Tonic<\/a> \u0434\u043b\u044f <code>gRPC<\/code><\/li>\n<li><a href=\"https:\/\/async.rs\/\">async-std<\/a> \u2014 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0441\u044f \u0431\u044b\u0442\u044c &#171;\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430&#187; \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432 <code>async::task<\/code><\/li>\n<li><a href=\"https:\/\/docs.rs\/smol\/latest\/smol\/\">smol<\/a> \u2014 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u044b\u0439<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u043c\u0435\u044e\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/fuchsia.googlesource.com\/fuchsia\/+\/refs\/heads\/main\/src\/lib\/fuchsia-async\/src\/lib.rs\">Fuchsia<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f &#171;\u0438\u043d\u0435\u0440\u0442\u043d\u044b\u043c\u0438&#187; \u0432 \u0442\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u043f\u0440\u043e\u0448\u0435\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u043c. \u042d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u0440\u043e\u043c\u0438\u0441\u043e\u0432 <code>JS<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p><strong>Tokio<\/strong><\/p>\n<p>  <\/p>\n<p><code>Tokio<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/li>\n<li>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/li>\n<li>\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::time;  async fn count_to(count: i32) {     for i in 1..=count {         println!(\"\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 \u0437\u0430\u0434\u0430\u0447\u0435: {i}!\");         time::sleep(time::Duration::from_millis(5)).await;     } }  #[tokio::main] async fn main() {     tokio::spawn(count_to(10));      for i in 1..5 {         println!(\"\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435: {i}\");         time::sleep(time::Duration::from_millis(5)).await;     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043c\u0430\u043a\u0440\u043e\u0441 <code>tokio::main<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code> \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439<\/li>\n<li>\u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>spawn<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u0443\u044e &#171;\u0437\u0430\u0434\u0430\u0447\u0443&#187;<\/li>\n<li>\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: <code>spawn<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>Future<\/code>, \u043c\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>.await<\/code> \u043d\u0430 <code>count_to()<\/code><\/li>\n<li>\u043f\u043e\u0447\u0435\u043c\u0443 <code>count_to()<\/code> \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e 10? \u042d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043c\u0435\u043d\u044b \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. <code>tokio::spawn()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a (handle), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0436\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f<\/li>\n<li>\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>tokio::spawn<\/code> \u043d\u0430 <code>count_to(10).await<\/code><\/li>\n<li>\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0439 <code>tokio::spawn()<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0417\u0430\u0434\u0430\u0447\u0438<\/strong><\/p>\n<p>  <\/p>\n<p><code>Rust<\/code> \u0438\u043c\u0435\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0437\u0430\u0434\u0430\u0447 (task system), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u043e\u0440\u043c\u043e\u0439 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0439\u0434\u0438\u043d\u0433\u0430 (threading).<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u0438\u043d \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u043c. \u042d\u0442\u043e\u0442 \u0444\u044c\u044e\u0447\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>poll<\/code>, \u0447\u0442\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0435\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (call stack). \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u043f\u0443\u0442\u0435\u043c \u043e\u043f\u0440\u043e\u0441\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener;  #[tokio::main] async fn main() -> io::Result&lt;()> {     let listener = TcpListener::bind(\"127.0.0.1:0\").await?;     println!(\"\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 {}\", listener.local_addr()?.port());      loop {         let (mut socket, addr) = listener.accept().await?;          println!(\"\u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 {addr:?}\");          tokio::spawn(async move {             socket.write_all(b\"\u041a\u0442\u043e \u0442\u044b?\\n\").await.expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u043a\u0435\u0442\u0430\");              let mut buf = vec![0; 1024];             let name_size = socket.read(&amp;mut buf).await.expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u043a\u0435\u0442\u0430\");             let name = std::str::from_utf8(&amp;buf[..name_size]).unwrap().trim();             let reply = format!(\"\u041f\u0440\u0438\u0432\u0435\u0442, {name}!\\n\");             socket.write_all(reply.as_bytes()).await.expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u043a\u0435\u0442\u0430\");         });     } }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 <code>async<\/code> \u0431\u043b\u043e\u043a. \u0422\u0430\u043a\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 \u043f\u043e\u0445\u043e\u0436\u0438 \u043d\u0430 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f, \u043d\u043e \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0418\u0445 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u044c\u044e\u0447\u0435\u0440, \u043a\u0430\u043a \u0443 <code>async fn<\/code><\/li>\n<li>\u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>?<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0440\u0435\u0439\u0442\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0430\u043b\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>tokio<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::mpsc::{self, Receiver};  async fn ping_handler(mut input: Receiver&lt;()>) {     let mut count: usize = 0;      while let Some(_) = input.recv().await {         count += 1;         println!(\"\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e {count} \u043f\u0438\u043d\u0433\u043e\u0432\");     }      println!(\"ping_handler \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\"); }  #[tokio::main] async fn main() {     let (sender, receiver) = mpsc::channel(32);     let ping_handler_task = tokio::spawn(ping_handler(receiver));     for i in 0..10 {         sender.send(()).await.expect(\"\u043f\u0440\u043e\u0432\u0430\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0438\u043d\u0433\u0430\");         println!(\"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e {} \u043f\u0438\u043d\u0433\u043e\u0432\", i + 1);     }      drop(sender);      ping_handler_task.await.expect(\"\u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a\"); }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u043d\u0430\u043b\u0430 \u043d\u0430 <code>3<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435<\/li>\n<li>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 <code>sync<\/code> \u043a\u0430\u043d\u0430\u043b\u043e\u0432, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435<\/li>\n<li>\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c <code>std::mem::drop<\/code>. \u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442? \u041f\u043e\u0447\u0435\u043c\u0443?<\/li>\n<li>\u043a\u0440\u0435\u0439\u0442 <a href=\"https:\/\/docs.rs\/flume\/latest\/flume\/\">Flume<\/a> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u0430\u043d\u0430\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043a\u0430\u043a <code>sync<\/code>, \u0442\u0430\u043a \u0438 <code>async send<\/code>, \u0438 <code>recv<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u0442\u044f\u0436\u0435\u043b\u044b\u043c\u0438 \u0434\u043b\u044f \u0426\u041f \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438<\/li>\n<li><code>async<\/code> \u043a\u0430\u043d\u0430\u043b\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 <code>future<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (control flow)<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"potok-upravleniya-fyucherov\">\u041f\u043e\u0442\u043e\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432<\/h2>\n<p>  <\/p>\n<p>\u0424\u044c\u044e\u0447\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u043e\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u041c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u044e\u0442 \u043a\u0430\u043a \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><strong>Join<\/strong><\/p>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>join_all<\/code> \u0436\u0434\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0433\u043e\u0442\u043e\u0432\u044b, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b. \u042d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>Promise.all<\/code> \u0432 <code>JavaScript<\/code> \u0438\u043b\u0438 <code>asyncio.gather<\/code> \u0432 <code>Python<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use anyhow::Result; use futures::future; use reqwest; use std::collections::HashMap;  async fn size_of_page(url: &amp;str) -> Result&lt;usize> {     let resp = reqwest::get(url).await?;     Ok(resp.text().await?.len()) }  #[tokio::main] async fn main() {     let urls: [&amp;str; 4] = [         \"https:\/\/google.com\",         \"https:\/\/httpbin.org\/ip\",         \"https:\/\/play.rust-lang.org\/\",         \"BAD_URL\",     ];     let futures_iter = urls.into_iter().map(size_of_page);     let results = future::join_all(futures_iter).await;     let page_sizes_dict: HashMap&lt;&amp;str, Result&lt;usize>> =         urls.into_iter().zip(results.into_iter()).collect();     println!(\"{:?}\", page_sizes_dict); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432 \u043d\u0435\u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u0442\u0438\u043f\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>std::future::join!<\/code> \u043d\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u043d\u0430\u0442\u044c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f <code>join_all()<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u0440\u0435\u0439\u0442\u0435 <code>futures<\/code>, \u043d\u043e \u0441\u043a\u043e\u0440\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0432 <code>std::future<\/code><\/li>\n<li>\u0440\u0438\u0441\u043a \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0444\u044c\u044e\u0447\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/li>\n<li>\u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>join_all()<\/code> \u0441 <code>join!<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u043b\u0443\u0436\u0431\u0435 <code>HTTP<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <code>tokio::time::sleep()<\/code> \u0432\u043e \u0444\u044c\u044e\u0447\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>future::join!<\/code>. \u042d\u0442\u043e \u043d\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f <code>select!<\/code>, \u043a\u0430\u043a \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435), \u0430 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b <code>join!<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>Select<\/strong><\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u0430 (select) \u0436\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u0438\u0437 \u043d\u0430\u0431\u043e\u0440\u0430 \u0438 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0412 <code>JavaScript<\/code> \u044d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>Promise.race<\/code>. \u0412 <code>Python<\/code> \u044d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>asyncio.wait(task_set, return_when=asyncio.FIRST_COMPLETED)<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0443 <code>match<\/code>, \u0442\u0435\u043b\u043e <code>select!<\/code> \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0442\u0432\u0435\u0439 (arms), \u043a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 <code>pattern = future => statement<\/code>. \u041a\u043e\u0433\u0434\u0430 <code>future<\/code> \u0433\u043e\u0442\u043e\u0432, \u0435\u0433\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f <code>pattern<\/code>. \u0417\u0430\u0442\u0435\u043c <code>statement<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>statement<\/code> \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043c\u0430\u043a\u0440\u043e\u0441\u0430 <code>select!<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::mpsc::{self, Receiver}; use tokio::time::{sleep, Duration};  #[derive(Debug, PartialEq)] enum Animal {     Cat { name: String },     Dog { name: String }, }  async fn first_animal_to_finish_race(     mut cat_rcv: Receiver&lt;String>,     mut dog_rcv: Receiver&lt;String>, ) -> Option&lt;Animal> {     tokio::select! {         cat_name = cat_rcv.recv() => Some(Animal::Cat { name: cat_name? }),         dog_name = dog_rcv.recv() => Some(Animal::Dog { name: dog_name? })     } }  #[tokio::main] async fn main() {     let (cat_sender, cat_receiver) = mpsc::channel(32);     let (dog_sender, dog_receiver) = mpsc::channel(32);      tokio::spawn(async move {         sleep(Duration::from_millis(500)).await;         cat_sender.send(String::from(\"\u0424\u0435\u043b\u0438\u043a\u0441\")).await.expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438\u043c\u0435\u043d\u0438 \u043a\u043e\u0442\u0430\");     });      tokio::spawn(async move {         sleep(Duration::from_millis(50)).await;         dog_sender.send(String::from(\"\u0420\u0435\u043a\u0441\")).await.expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438\u043c\u0435\u043d\u0438 \u0441\u043e\u0431\u0430\u043a\u0438\");     });      let winner = first_animal_to_finish_race(cat_receiver, dog_receiver)         .await         .expect(\"\u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044f\");      println!(\"\u041f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f {winner:?}\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0433\u043e\u043d\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u0448\u043a\u043e\u0439 \u0438 \u0441\u043e\u0431\u0430\u043a\u043e\u0439. <code>first_animal_to_finish_race()<\/code> &#171;\u0441\u043b\u0443\u0448\u0430\u0435\u0442&#187; (listening) \u043e\u0431\u0430 \u043a\u0430\u043d\u0430\u043b\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u043c\u044f \u0441\u043e\u0431\u0430\u043a\u0438 \u043f\u0440\u0438\u0431\u044b\u0432\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 50 \u043c\u0441, \u0441\u043e\u0431\u0430\u043a\u0430 \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u0443 \u043a\u043e\u0448\u043a\u0438, \u0438\u043c\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u0431\u044b\u0432\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 500 \u043c\u0441<\/li>\n<li>\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u043c\u0435\u0441\u0442\u043e <code>channel<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>oneshot<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>send<\/code><\/li>\n<li>\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0433\u043e\u043d\u043a\u0435 \u0434\u0435\u0434\u043b\u0430\u0439\u043d, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044f \u0432\u044b\u0431\u043e\u0440 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u043e\u0432<\/li>\n<li>\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e <code>select!<\/code> \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0432\u0448\u0438\u0435 \u0432\u0435\u0442\u0432\u0438, \u0447\u0442\u043e \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 \u0438\u0445 \u0444\u044c\u044e\u0447\u0435\u0440\u044b. <code>select!<\/code> \u043b\u0435\u0433\u0447\u0435 \u0432\u0441\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u043a\u0440\u043e\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u044b<br \/> \n<ul>\n<li>\u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 <code>&amp;mut future<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0444\u044c\u044e\u0447\u0435\u0440\u0430, \u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u043e\u0437\u0436\u0435<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"lovushki-asyncawait\">\u041b\u043e\u0432\u0443\u0448\u043a\u0438 async\/await<\/h2>\n<p>  <\/p>\n<p><code>async\/await<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c <code>async\/await<\/code> \u0432 <code>Rust<\/code> \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 \u0438 \u043b\u043e\u0432\u0443\u0448\u043a\u0438, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u0432 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435.<\/p>\n<p>  <\/p>\n<p><strong>\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f<\/strong><\/p>\n<p>  <\/p>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0426\u041f \u0431\u0443\u0434\u0443\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f (executor) \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043e\u0431\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0443\u0442\u044c \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0442\u0430\u043c, \u0433\u0434\u0435 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use futures::future::join_all; use std::time::Instant;  async fn sleep_ms(start: &amp;Instant, id: u64, duration_ms: u64) {     std::thread::sleep(std::time::Duration::from_millis(duration_ms));     println!(         \"\u0444\u044c\u044e\u0447\u0435\u0440 {id} \u0441\u043f\u0430\u043b \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 {duration_ms} \u043c\u0441, \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u043f\u043e\u0441\u043b\u0435 {} \u043c\u0441\",         start.elapsed().as_millis()     ); }  #[tokio::main(flavor = \"current_thread\")] async fn main() {     let start = Instant::now();     let sleep_futures = (1..=10).map(|t| sleep_ms(&amp;start, t, t * 10));     join_all(sleep_futures).await; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043a\u043e\u0434 \u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432 \u0440\u0435\u0436\u0438\u043c \u0441\u043d\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0430 \u043d\u0435 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/li>\n<li><code>flavor = \"current_thread\"<\/code> \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442 \u0431\u043e\u043b\u0435\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c, \u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0432 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438<\/li>\n<li>\u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0435 <code>std::thread::sleep<\/code> \u043d\u0430 <code>tokio::time::sleep<\/code> \u0438 \u0434\u043e\u0436\u0434\u0438\u0442\u0435\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430<\/li>\n<li>\u0434\u0440\u0443\u0433\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <code>tokio::task::spawn_blocking<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0432 <code>future<\/code>, \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f<\/li>\n<li>\u043e \u0437\u0430\u0434\u0430\u0447\u0430\u0445 \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043e \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u041e\u0421. \u041e\u043d\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 1 \u043a 1, \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0434\u0430\u0447 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u041e\u0421. \u042d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 <code>FFI<\/code>, \u0433\u0434\u0435 \u044d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438\u043b\u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u041e\u0421 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>CUDA<\/code>). \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u043e\u0442\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 <code>tokio::task::spawn_blocking<\/code><\/li>\n<li>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e. \u0423\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430 \u043d\u0430\u0434 <code>.await<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>Pin<\/strong><\/p>\n<p>  <\/p>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0442\u0438\u043f\u044b, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0435 \u0442\u0440\u0435\u0439\u0442 <code>Future<\/code>. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u044b\u0435, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u044c\u044e\u0447\u0435\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u044b\u0439 (pinned) \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c. <code>Pin<\/code> \u2014 \u044d\u0442\u043e \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430 \u0441\u0441\u044b\u043b\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use tokio::sync::{mpsc, oneshot}; use tokio::task::spawn; use tokio::time::{sleep, Duration};  \/\/ \u0420\u0430\u0431\u043e\u0447\u0430\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u0438\u0442 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \/\/ \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0432 \u043a\u0430\u043d\u0430\u043b `respond_on` #[derive(Debug)] struct Work {     input: u32,     respond_on: oneshot::Sender&lt;u32>, }  \/\/ \u0412\u043e\u0440\u043a\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 (queue) \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0435\u0435 async fn worker(mut work_queue: mpsc::Receiver&lt;Work>) {     let mut iterations = 0;     loop {         tokio::select! {             Some(work) = work_queue.recv() => {                 sleep(Duration::from_millis(10)).await; \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \"\u0440\u0430\u0431\u043e\u0442\u0443\"                 work.respond_on                     .send(work.input * 1000)                     .expect(\"\u043f\u0440\u043e\u0432\u0430\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430\");                 iterations += 1;             }             \/\/ TODO: \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u043a\u0430\u0436\u0434\u044b\u0439 100 \u043c\u0441         }     } }  \/\/ \"\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u0435\u043b\u044c\" (requester), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0436\u0434\u0435\u0442 \u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f async fn do_work(work_queue: &amp;mpsc::Sender&lt;Work>, input: u32) -> u32 {     let (tx, rx) = oneshot::channel();     work_queue         .send(Work { input, respond_on: tx })         .await         .expect(\"\u043f\u0440\u043e\u0432\u0430\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\");     rx.await.expect(\"\u043f\u0440\u043e\u0432\u0430\u043b \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430\") }  #[tokio::main] async fn main() {     let (tx, rx) = mpsc::channel(10);     spawn(worker(rx));     for i in 0..100 {         let resp = do_work(&amp;tx, i).await;         println!(\"\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043b\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 {i}: {resp}\");     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0430\u043a\u0442\u043e\u0440\u0430 (actor pattern). \u0410\u043a\u0442\u043e\u0440\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 <code>select!<\/code> \u0432 \u0446\u0438\u043a\u043b\u0435<\/li>\n<li>\u044d\u0442\u043e \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0443\u0440\u043e\u043a\u043e\u0432, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0435 \u0442\u043e\u0440\u043e\u043f\u0438\u0442\u0435\u0441\u044c<br \/> \n<ul>\n<li>\u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 <code>_ = sleep(Duration::from_millis(100)) => { println!(..) }<\/code> \u0432 <code>select!<\/code>. \u042d\u0442\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f. \u041f\u043e\u0447\u0435\u043c\u0443?<\/li>\n<li>\u0442\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 <code>timeout_fut<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u044d\u0442\u043e\u0442 \u0444\u044c\u044e\u0447\u0435\u0440 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 <code>loop<\/code>:<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"rust\">let mut timeout_fut = sleep(Duration::from_millis(100)); loop {     select! {         ..,         _ = timeout_fut => { println!(..); },     } }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0418\u0437\u0443\u0447\u0438\u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 <code>&amp;mut<\/code> \u0432 <code>timeout_fut<\/code> \u0432 <code>select!<\/code> \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f, \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>Box::pin<\/code>:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"rust\">let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100))); loop {     select! {         ..,         _ = &amp;mut timeout_fut => { println!(..); },     } }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u044d\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043d\u043e \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0442\u0430\u0439\u043c-\u0430\u0443\u0442\u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 <code>Poll::Ready<\/code> (\u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0444\u044c\u044e\u0447\u0435\u0440). \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c <code>timeout_fut<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442<br \/> \n<ul>\n<li><code>Box<\/code> \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c \u0432 \u043a\u0443\u0447\u0435. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 <code>std::pin::pin!<\/code> \u2014 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043d\u043e \u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0444\u044c\u044e\u0447\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f<\/li>\n<li>\u0434\u0440\u0443\u0433\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u2014 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>pin<\/code>, \u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u043d\u0430\u043b <code>oneshot<\/code> \u043a\u0430\u0436\u0434\u044b\u0435 100 \u043c\u0441<\/li>\n<li>\u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u0441\u0435\u0431\u044f, \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u0441\u0441\u044b\u043b\u0430\u044e\u0449\u0438\u043c\u0438\u0441\u044f (self-referential). \u041e\u0431\u044b\u0447\u043d\u043e \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439 (borrow checker) \u0432 <code>Rust<\/code> \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0436\u0438\u0442\u044c \u0434\u043e\u043b\u044c\u0448\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439<\/li>\n<li><code>Pin<\/code> \u2014 \u044d\u0442\u043e \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 \u0441\u0441\u044b\u043b\u043a\u043e\u0439. \u041e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f<\/li>\n<li>\u043c\u0435\u0442\u043e\u0434 <code>poll<\/code> \u0442\u0440\u0435\u0439\u0442\u0430 <code>Future<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <code>Pin&lt;&amp;mut Self><\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>&amp;mut Self<\/code> \u0434\u043b\u044f \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440. \u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0439\u0442\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0432 \u0442\u0440\u0435\u0439\u0442\u0430\u0445 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 <code>Rust<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u0435\u0439\u0442 <a href=\"https:\/\/docs.rs\/async-trait\/latest\/async_trait\/\">async_trait<\/a> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u043a\u0440\u043e\u0441 \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use async_trait::async_trait; use std::time::Instant; use tokio::time::{sleep, Duration};  #[async_trait] trait Sleeper {     async fn sleep(&amp;self); }  struct FixedSleeper {     sleep_ms: u64, }  #[async_trait] impl Sleeper for FixedSleeper {     async fn sleep(&amp;self) {         sleep(Duration::from_millis(self.sleep_ms)).await;     } }  async fn run_all_sleepers_multiple_times(     sleepers: Vec&lt;Box&lt;dyn Sleeper>>,     n_times: usize, ) {     for _ in 0..n_times {         println!(\"running all sleepers..\");         for sleeper in &amp;sleepers {             let start = Instant::now();             sleeper.sleep().await;             println!(\"slept for {}ms\", start.elapsed().as_millis());         }     } }  #[tokio::main] async fn main() {     let sleepers: Vec&lt;Box&lt;dyn Sleeper>> = vec![         Box::new(FixedSleeper { sleep_ms: 50 }),         Box::new(FixedSleeper { sleep_ms: 100 }),     ];     run_all_sleepers_multiple_times(sleepers, 5).await; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>async_trait<\/code> \u043f\u0440\u043e\u0441\u0442 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u043d\u043e \u0443\u0447\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u043a\u0443\u0447\u0435. \u042d\u0442\u043e \u0432\u043b\u0435\u0447\u0435\u0442 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/li>\n<li>\u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e &#171;\u0441\u043f\u044f\u0449\u0443\u044e&#187; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u0432 \u0432\u0435\u043a\u0442\u043e\u0440<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041e\u0442\u043c\u0435\u043d\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u044c\u044e\u0447\u0435\u0440\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c. \u042d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043c\u0435\u043d\u043e\u0439 (cancellation) \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0434\u0430\u0436\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043c\u0435\u043d\u044b \u0444\u044c\u044e\u0447\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u043d \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043b\u0438 \u0442\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::io::{self, ErrorKind}; use std::time::Duration; use tokio::io::{AsyncReadExt, AsyncWriteExt, DuplexStream};  struct LinesReader {     stream: DuplexStream, }  impl LinesReader {     fn new(stream: DuplexStream) -> Self {         Self { stream }     }      async fn next(&amp;mut self) -> io::Result&lt;Option&lt;String>> {         let mut bytes = Vec::new();         let mut buf = [0];         while self.stream.read(&amp;mut buf[..]).await? != 0 {             bytes.push(buf[0]);             if buf[0] == b'\\n' {                 break;             }         }         if bytes.is_empty() {             return Ok(None);         }         let s = String::from_utf8(bytes)             .map_err(|_| io::Error::new(ErrorKind::InvalidData, \"\u043d\u0435 UTF-8\"))?;         Ok(Some(s))     } }  async fn slow_copy(source: String, mut dest: DuplexStream) -> std::io::Result&lt;()> {     for b in source.bytes() {         dest.write_u8(b).await?;         tokio::time::sleep(Duration::from_millis(10)).await     }     Ok(()) }  #[tokio::main] async fn main() -> std::io::Result&lt;()> {     let (client, server) = tokio::io::duplex(5);     let handle = tokio::spawn(slow_copy(\"\u043f\u0440\u0438\u0432\u0435\u0442\\n\u043f\u0440\u0438\u0432\u0435\u0442\\n\".to_owned(), client));      let mut lines = LinesReader::new(server);     let mut interval = tokio::time::interval(Duration::from_millis(60));     loop {         tokio::select! {             _ = interval.tick() => println!(\"\u0442\u0438\u043a!\"),             line = lines.next() => if let Some(l) = line? {                 print!(\"{}\", l)             } else {                 break             },         }     }     handle.await.unwrap()?;     Ok(()) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u043c\u0435\u043d\u044b. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e API \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0432\u0430\u0448\u0430 <code>async fn<\/code><\/li>\n<li>\u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>panic!<\/code> \u0438 <code>?<\/code>, \u043e\u0442\u043c\u0435\u043d\u0430 \u2014 \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a)<\/li>\n<li>\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438<br \/> \n<ul>\n<li>\u0435\u0441\u043b\u0438 \u0432\u0435\u0442\u0432\u044c <code>tick()<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u043e\u0439, <code>next()<\/code> \u0438 \u0435\u0433\u043e <code>buf<\/code> \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f<\/li>\n<li><code>LinesReader<\/code> \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b \u043f\u0443\u0442\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <code>buf<\/code> \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443:<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"rust\">struct LinesReader {     stream: DuplexStream,     bytes: Vec&lt;u8>,     buf: [u8; 1], }  impl LinesReader {     fn new(stream: DuplexStream) -> Self {         Self { stream, bytes: Vec::new(), buf: [0] }     }     async fn next(&amp;mut self) -> io::Result&lt;Option&lt;String>> {         \/\/ ...         let raw = std::mem::take(&amp;mut self.bytes);         let s = String::from_utf8(raw)         \/\/ ...     } }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/time\/struct.Interval.html#method.tick\">Interval::tick<\/a> \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442, \u0431\u044b\u043b \u043b\u0438 &#171;\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d&#187; (delivered) \u0442\u0438\u043a<\/li>\n<li><a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/io\/trait.AsyncReadExt.html#method.read\">AsyncReadExt::read<\/a> \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043b\u0438\u0431\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f, \u043b\u0438\u0431\u043e \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435<\/li>\n<li><a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/io\/trait.AsyncBufReadExt.html#method.read_line\">AsyncBufReadExt::read_line<\/a>, \u043a\u0430\u043a \u0438 \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0434\u043b\u044f \u043e\u0442\u043c\u0435\u043d\u044b. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u0441\u043c. \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"uprazhneniya-1\">\u0423\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0432\u044b\u043a\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c <code>Rust<\/code>, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u0434\u0432\u0430 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043e\u0431\u0435\u0434\u0430\u044e\u0449\u0438\u0435 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u044b \u2014 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e <code>Rust<\/code><\/li>\n<li>\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0447\u0430\u0442\u0430<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u0435\u0434\u0430\u044e\u0449\u0438\u0435 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u044b<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">use std::sync::Arc; use tokio::sync::mpsc::{self, Sender}; use tokio::sync::Mutex; use tokio::time;  struct Fork;  struct Philosopher {     name: String,     \/\/ left_fork: ...     \/\/ right_fork: ...     \/\/ thoughts: ... }  impl Philosopher {     async fn think(&amp;self) {         self.thoughts             .send(format!(\"\u042d\u0432\u0440\u0438\u043a\u0430! {} \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b(\u0430) \u043d\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e!\", &amp;self.name))             .await             .unwrap();     }      async fn eat(&amp;self) {         \/\/ \u041f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u0435 \u0432\u0438\u043b\u043a\u0438         println!(\"{} \u0435\u0441\u0442...\", &amp;self.name);         time::sleep(time::Duration::from_millis(5)).await;     } }  static PHILOSOPHERS: &amp;[&amp;str] =      &amp;[\"\u0421\u043e\u043a\u0440\u0430\u0442\", \"\u0413\u0438\u043f\u0430\u0442\u0438\u044f\", \"\u041f\u043b\u0430\u0442\u043e\u043d\", \"\u0410\u0440\u0438\u0441\u0442\u043e\u0442\u0435\u043b\u044c\", \"\u041f\u0438\u0444\u0430\u0433\u043e\u0440\"];  #[tokio::main] async fn main() {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0438\u043b\u043a\u0438      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432      \/\/ \u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u044f\u0435\u0442 \u0438 \u0435\u0441\u0442 100 \u0440\u0430\u0437      \/\/ \u0412\u044b\u0432\u043e\u0434\u0438\u043c \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c <code>Rust<\/code> \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>tokio<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">[package] name = \"dining-philosophers-async\" version = \"0.1.0\" edition = \"2021\"  [dependencies] tokio = { version = \"1.26.0\", features = [\"sync\", \"time\", \"macros\", \"rt-multi-thread\"] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0432\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Mutex<\/code> \u0438 \u043c\u043e\u0434\u0443\u043b\u044c <code>mpsc<\/code> \u0438\u0437 <code>tokio<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"rust\">use std::sync::Arc; use tokio::sync::mpsc::{self, Sender}; use tokio::sync::Mutex; use tokio::time;  struct Fork;  struct Philosopher {     name: String,     left_fork: Arc&lt;Mutex&lt;Fork>>,     right_fork: Arc&lt;Mutex&lt;Fork>>,     thoughts: Sender&lt;String>, }  impl Philosopher {     async fn think(&amp;self) {         self.thoughts             .send(format!(\"\u042d\u0432\u0440\u0438\u043a\u0430! {} \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b(\u0430) \u043d\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e!\", &amp;self.name))             .await             .unwrap();     }      async fn eat(&amp;self) {          \/\/ \u041f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u0435 \u0432\u0438\u043b\u043a\u0438         let (_left_fork, _right_fork) = loop {             \/\/ \u0411\u0435\u0440\u0435\u043c \u0432\u0438\u043b\u043a\u0438...             let left_fork = self.left_fork.try_lock();             let right_fork = self.right_fork.try_lock();              let Ok(left_fork) = left_fork else {                 \/\/ \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043b\u0435\u0432\u0443\u044e \u0432\u0438\u043b\u043a\u0443, \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043f\u0440\u0430\u0432\u0443\u044e \u0432\u0438\u043b\u043a\u0443,                 \/\/ \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0430\u043c                 drop(right_fork);                 time::sleep(time::Duration::from_millis(1)).await;                 continue;             };              let Ok(right_fork) = right_fork else {                 \/\/ \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u0440\u0430\u0432\u0443\u044e \u0432\u0438\u043b\u043a\u0443, \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0435\u0432\u0443\u044e \u0432\u0438\u043b\u043a\u0443,                 \/\/ \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0430\u043c                 drop(left_fork);                 time::sleep(time::Duration::from_millis(1)).await;                 continue;             };              break (left_fork, right_fork);         };          println!(\"{} \u0435\u0441\u0442...\", &amp;self.name);         time::sleep(time::Duration::from_millis(5)).await;         \/\/ \u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c     } }  static PHILOSOPHERS: &amp;[&amp;str] =    &amp;[\"\u0421\u043e\u043a\u0440\u0430\u0442\", \"\u0413\u0438\u043f\u0430\u0442\u0438\u044f\", \"\u041f\u043b\u0430\u0442\u043e\u043d\", \"\u0410\u0440\u0438\u0441\u0442\u043e\u0442\u0435\u043b\u044c\", \"\u041f\u0438\u0444\u0430\u0433\u043e\u0440\"];  #[tokio::main] async fn main() {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0438\u043b\u043a\u0438     let mut forks = vec![];     (0..PHILOSOPHERS.len()).for_each(|_| forks.push(Arc::new(Mutex::new(Fork))));      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432     let (philosophers, mut rx) = {         let mut philosophers = vec![];          let (tx, rx) = mpsc::channel(10);          for (i, name) in PHILOSOPHERS.iter().enumerate() {             let left_fork = Arc::clone(&amp;forks[i]);             let right_fork = Arc::clone(&amp;forks[(i + 1) % PHILOSOPHERS.len()]);              philosophers.push(Philosopher {                 name: name.to_string(),                 left_fork,                 right_fork,                 thoughts: tx.clone(),             });         }          (philosophers, rx)         \/\/ `tx` \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0437\u0436\u0435     };      \/\/ \u041a\u0430\u0436\u0434\u044b\u0439 \u0444\u0438\u043b\u043e\u0441\u043e\u0444 \u0434\u0443\u043c\u0430\u0435\u0442 \u0438 \u0435\u0441\u0442 100 \u0440\u0430\u0437     for phil in philosophers {         tokio::spawn(async move {             for _ in 0..100 {                 phil.think().await;                 phil.eat().await;             }         });     }      \/\/ \u0412\u044b\u0432\u043e\u0434\u0438\u043c \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u043e\u0432     while let Some(thought) = rx.recv().await {         println!(\"{thought}\");     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><strong>\u0427\u0430\u0442<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u0430. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u0438 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u044e\u0442 \u0441\u0432\u043e\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041a\u043b\u0438\u0435\u043d\u0442 \u0447\u0438\u0442\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0432\u043e\u0434 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0421\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 (broadcast) \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/sync\/broadcast\/fn.channel.html\">\u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b<\/a> \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 <a href=\"https:\/\/docs.rs\/tokio-websockets\/\">tokio_websockets<\/a> \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 <code>Cargo.toml<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">[package] name = \"chat-async\" version = \"0.1.0\" edition = \"2021\"  [dependencies] futures-util = { version = \"0.3.30\", features = [\"sink\"] } http = \"1.0.0\" tokio = { version = \"1.28.1\", features = [\"full\"] } tokio-websockets = { version = \"0.5.1\", features = [\"client\", \"fastrand\", \"server\", \"sha1_smol\"] }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 API<\/em><\/p>\n<p>  <\/p>\n<p>\u0412\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 <code>tokio<\/code> \u0438 <code>tokio_websockets<\/code>. \u041f\u043e\u0442\u0440\u0430\u0442\u044c\u0442\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043d\u0443\u0442 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 API:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/docs.rs\/futures-util\/0.3.28\/futures_util\/stream\/trait.StreamExt.html#method.next\">StreamExt::next()<\/a>, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0439 <code>WebSocketStream<\/code> \u2014 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442\u043e\u0432<\/li>\n<li><a href=\"https:\/\/docs.rs\/futures-util\/0.3.28\/futures_util\/sink\/trait.SinkExt.html#method.send\">SinkExt::send()<\/a>, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0439 <code>WebSocketStream<\/code> \u2014 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u043e\u0442\u043e\u043a \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442\u043e\u0432<\/li>\n<li><a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/io\/struct.Lines.html#method.next_line\">Lines::next_line()<\/a> \u2014 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0432\u043e\u0434<\/li>\n<li><a href=\"https:\/\/docs.rs\/tokio\/latest\/tokio\/sync\/broadcast\/struct.Sender.html#method.subscribe\">Sender::subscribe()<\/a> \u2014 \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043d\u0430\u043b<\/li>\n<\/ul>\n<p>  <\/p>\n<p><em>\u0414\u0432\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430<\/em><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b (binary) \u0438 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b <code>src\/main.rs<\/code>. \u041d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430. \u041e\u0434\u0438\u043d \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u043d\u043e \u043c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u043e\u0431\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u0432 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0435\u043a\u0442. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src\/bin<\/code> (\u0441\u043c. <a href=\"https:\/\/doc.rust-lang.org\/cargo\/reference\/cargo-targets.html#binaries\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e<\/a>).<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 <code>src\/bin\/server.rs<\/code> \u0438 <code>src\/bin\/client.rs<\/code>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/ src\/bin\/server.rs use futures_util::sink::SinkExt; use futures_util::stream::StreamExt; use std::error::Error; use std::net::SocketAddr; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::broadcast::{channel, Sender}; use tokio_websockets::{Message, ServerBuilder, WebSocketStream};  async fn handle_connection(     addr: SocketAddr,     mut ws_stream: WebSocketStream&lt;TcpStream>,     bcast_tx: Sender&lt;String>, ) -> Result&lt;(), Box&lt;dyn Error + Send + Sync>> {     todo!(\"\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0439 \u043c\u0435\u043d\u044f\") }  #[tokio::main] async fn main() -> Result&lt;(), Box&lt;dyn Error + Send + Sync>> {     let (bcast_tx, _) = channel(16);      let listener = TcpListener::bind(\"127.0.0.1:2000\").await?;     println!(\"\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 2000\");      loop {         let (socket, addr) = listener.accept().await?;         println!(\"\u0417\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 {addr:?}\");         let bcast_tx = bcast_tx.clone();         tokio::spawn(async move {             \/\/ \u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u044b\u0440\u043e\u0439 \u043f\u043e\u0442\u043e\u043a TCP \u0432 \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442             let ws_stream = ServerBuilder::new().accept(socket).await?;              handle_connection(addr, ws_stream, bcast_tx).await         });     } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/ src\/bin\/client.rs use futures_util::stream::StreamExt; use futures_util::SinkExt; use http::Uri; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio_websockets::{ClientBuilder, Message};  #[tokio::main] async fn main() -> Result&lt;(), tokio_websockets::Error> {     let (mut ws_stream, _) =         ClientBuilder::from_uri(Uri::from_static(\"ws:\/\/127.0.0.1:2000\"))             .connect()             .await?;      let stdin = tokio::io::stdin();     let mut stdin = BufReader::new(stdin).lines();      todo!(\"\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0439 \u043c\u0435\u043d\u044f\") }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u0417\u0430\u043f\u0443\u0441\u043a \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u043e\u0432<\/em><\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cargo run --bin server<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cargo run --bin client<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u0417\u0430\u0434\u0430\u0447\u0438<\/em><\/p>\n<p>  <\/p>\n<ul>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>handle_connection<\/code> \u0432 <code>src\/bin\/server.rs<\/code><br \/> \n<ul>\n<li>\u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>tokio::select!<\/code> \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0432\u0443\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435. \u041e\u0434\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c. \u0414\u0440\u0443\u0433\u0430\u044f \u2014 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/li>\n<\/ul>\n<\/li>\n<li>\u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code> \u0432 <code>src\/bin\/client.rs<\/code><br \/> \n<ul>\n<li>\u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>tokio::select!<\/code> \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0432\u0443\u0445 \u0437\u0430\u0434\u0430\u0447: 1) \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0438 \u0438\u0445 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0443; 2) \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0438\u0445 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/li>\n<\/ul>\n<\/li>\n<li>\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u0441\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c, \u043a\u0440\u043e\u043c\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f<\/li>\n<\/ul>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"rust\">\/\/ src\/bin\/server.rs use futures_util::sink::SinkExt; use futures_util::stream::StreamExt; use std::error::Error; use std::net::SocketAddr; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::broadcast::{channel, Sender}; use tokio_websockets::{Message, ServerBuilder, WebSocketStream};  async fn handle_connection(     addr: SocketAddr,     mut ws_stream: WebSocketStream&lt;TcpStream>,     bcast_tx: Sender&lt;String>, ) -> Result&lt;(), Box&lt;dyn Error + Send + Sync>> {      ws_stream         .send(Message::text(\"\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u0447\u0430\u0442! \u041e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\".to_string()))         .await?;     let mut bcast_rx = bcast_tx.subscribe();      \/\/ \u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0432\u0443\u0445 \u0437\u0430\u0434\u0430\u0447:     \/\/ 1) \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 `ws_stream` \u0438 \u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c     \/\/ 2) \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 `bcast_rx` \u0438 \u0438\u0445 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0443     loop {         tokio::select! {             incoming = ws_stream.next() => {                 match incoming {                     Some(Ok(msg)) => {                         if let Some(text) = msg.as_text() {                             println!(\"{addr:?}: {text:?}\");                             bcast_tx.send(text.into())?;                         }                     }                     Some(Err(err)) => return Err(err.into()),                     None => return Ok(()),                 }             }             msg = bcast_rx.recv() => {                 ws_stream.send(Message::text(msg?)).await?;             }         }     } }  #[tokio::main] async fn main() -> Result&lt;(), Box&lt;dyn Error + Send + Sync>> {     let (bcast_tx, _) = channel(16);      let listener = TcpListener::bind(\"127.0.0.1:2000\").await?;     println!(\"\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 2000\");      loop {         let (socket, addr) = listener.accept().await?;         println!(\"\u0417\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 {addr:?}\");         let bcast_tx = bcast_tx.clone();         tokio::spawn(async move {             \/\/ \u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u044b\u0440\u043e\u0439 \u043f\u043e\u0442\u043e\u043a TCP \u0432 \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442             let ws_stream = ServerBuilder::new().accept(socket).await?;              handle_connection(addr, ws_stream, bcast_tx).await         });     } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/ src\/bin\/client.rs use futures_util::stream::StreamExt; use futures_util::SinkExt; use http::Uri; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio_websockets::{ClientBuilder, Message};  #[tokio::main] async fn main() -> Result&lt;(), tokio_websockets::Error> {     let (mut ws_stream, _) =         ClientBuilder::from_uri(Uri::from_static(\"ws:\/\/127.0.0.1:2000\"))             .connect()             .await?;      let stdin = tokio::io::stdin();     let mut stdin = BufReader::new(stdin).lines();      \/\/ \u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439     loop {         tokio::select! {             incoming = ws_stream.next() => {                 match incoming {                     Some(Ok(msg)) => {                         if let Some(text) = msg.as_text() {                             println!(\"\u041e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430: {}\", text);                         }                     },                     Some(Err(err)) => return Err(err.into()),                     None => return Ok(()),                 }             }             res = stdin.next_line() => {                 match res {                     Ok(None) => return Ok(()),                     Ok(Some(line)) => ws_stream.send(Message::text(line.to_string())).await?,                     Err(err) => return Err(err.into()),                 }             }          }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043a\u043e\u043d\u0435\u0446 \u0431\u043e\u043d\u0443\u0441\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430.<\/p>\n<p>  <\/p>\n<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/doc.rust-lang.ru\/book\">\u041a\u043d\u0438\u0433\u0430\/\u0443\u0447\u0435\u0431\u043d\u0438\u043a \u043f\u043e Rust<\/a> (\u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435) \u2014 \u0433\u043b\u0430\u0432\u044b 16 \u0438 20<\/li>\n<li><a href=\"https:\/\/github.com\/rust-lang\/rustlings\">rustlings<\/a> \u2014 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 20<\/li>\n<li><a href=\"https:\/\/doc.rust-lang.ru\/stable\/rust-by-example\/\">Rust \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445<\/a> (\u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435) \u2014 \u043f\u0440\u0438\u043c\u0435\u0440\u044b 20.1 \u0438 20.2<\/li>\n<\/ul>\n<p>  <\/p>\n<p>Happy coding!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<p><a href=\"https:\/\/timeweb.cloud\/vds-vps?utm_source=habr&amp;utm_medium=banner&amp;utm_campaign\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\"\/><\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/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\/articles\/802609\/\"> https:\/\/habr.com\/ru\/articles\/802609\/<\/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-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/fj\/yi\/qn\/fjyiqnduv3l-rdgxnbu_t_qpgxk.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/fj\/yi\/qn\/fjyiqnduv3l-rdgxnbu_t_qpgxk.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>Hello world!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0431\u043e\u043d\u0443\u0441\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043f\u043e <a href=\"https:\/\/www.rust-lang.org\/ru\/\">Rust<\/a>.<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/790556\/\">\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/794941\/\">\u0412\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/796567\/\">\u0422\u0440\u0435\u0442\u044c\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/companies\/timeweb\/articles\/801201\/\">\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p><a href=\"https:\/\/my-js.org\/docs\/guide\/rust\/\">\u0414\u0440\u0443\u0433\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0432\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043d\u0430 <a href=\"https:\/\/google.github.io\/comprehensive-rust\/index.html\">Comprehensive Rust<\/a> \u2014 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e <code>Rust<\/code> \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>Android<\/code> \u0432 <code>Google<\/code> \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043d\u0430 \u043b\u044e\u0434\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u044e\u0442 \u043b\u044e\u0431\u044b\u043c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0415\u0449\u0435 \u0440\u0430\u0437: \u044d\u0442\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043d\u0430 \u0442\u0435\u0445, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043a\u043e\u0434\u0438\u0442\u044c ?<\/p>\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-371707","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371707","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=371707"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371707\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371707"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371707"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}