{"id":240525,"date":"2014-10-16T14:49:03","date_gmt":"2014-10-16T10:49:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=240525"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=240525","title":{"rendered":"<span class=\"post_title\">\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c 2: \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f \u0441\u043a\u0432\u043e\u0437\u044c \u043f\u043e\u0440\u0442\u0430\u043b\u044b<\/span>"},"content":{"rendered":"<div class=\"content html_format\">     \t<a href=\"http:\/\/habrahabr.ru\/company\/yandex\/blog\/240525\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/f0a\/1c5\/0ac\/f0a1c50ac50944079d72728394c600f7.jpeg\" width=\"640\" \/><\/div>\n<p><\/a><\/p>\n<p>  \u041d\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0438 \u0433\u043e\u0434\u0430, \u043a\u0430\u043a \u044f \u0434\u043e\u0431\u0440\u0430\u043b\u0441\u044f \u0434\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442 \u0438\u0434\u0435\u0438 \u0442\u043e\u0439, \u0441\u0430\u043c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c <a href=\"http:\/\/habrahabr.ru\/post\/201826\/\">[1]<\/a>. \u0412 \u043d\u0435\u0439 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0430 \u043c\u043e\u0449\u044c \u0438 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438 (race-condition), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0431\u043e\u043d\u0443\u0441.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0417\u0430 \u0432\u0441\u0451 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f <a href=\"http:\/\/habrahabr.ru\/post\/201826\/\">\u043f\u0435\u0440\u0432\u0430\u044f<\/a> \u0441\u0442\u0430\u0442\u044c\u044f \u0443\u0436\u0435 \u0432\u044b\u0431\u0438\u043b\u0430\u0441\u044c \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0442\u043e\u043f.  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/64d\/0c1\/cce\/64d0c1ccedc447b7bcdf413c873dd670.png\" width=\"640\" \/><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/f92\/a97\/512\/f92a97512def46809eccd385bec4a996.png\" width=\"640\" \/><\/div>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/a85\/726\/2ff\/a857262ff9144591bfebcc7b622932bb.jpeg\" width=\"640\" \/><\/div>\n<h2>\u0417\u0430\u0434\u0430\u0447\u0430<\/h2>\n<p>  \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0435\u0437\u0430\u043c\u044b\u0441\u043b\u043e\u0432\u0430\u0442\u0430 \u0438 \u0437\u0432\u0443\u0447\u0438\u0442 \u0442\u0430\u043a:<br \/>  <b>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u044f\u0436\u0435\u043b\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e \u0441\u0435\u0442\u0438 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0432 UI.<\/b><\/p>\n<p>  \u0411\u0443\u0434\u0435\u043c \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u00ab\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435\u00bb \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 UI:  <\/p>\n<ol>\n<li>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0438\u0437 UI-\u043f\u043e\u0442\u043e\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0435-\u043b\u0438\u0431\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435.<\/li>\n<li>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 UI.<\/li>\n<li>\u041c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c UI, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e.<\/li>\n<\/ol>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u00ab\u0432\u0435\u0441\u0435\u043b\u044b\u0435\u00bb \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430:  <\/p>\n<ol>\n<li>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 \u0441\u0435\u0442\u044c\u044e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u043c \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/li>\n<li>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u044b\u0439 \u043a\u0435\u0448, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0438\u0441\u044c.<\/li>\n<li>\u041f\u0435\u0440\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043e\u0442\u0434\u0430\u0447\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/li>\n<\/ol>\n<p>  \u0417\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0430\u0441\u043f\u0435\u043a\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:  <\/p>\n<ol>\n<li>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u0443\u044e, \u0430 \u043d\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043a\u0435\u0448\u0438 (\u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043f\u0430\u043c\u044f\u0442\u044c).<\/li>\n<li>\u0427\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 \u043a\u0435\u0448\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u043c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043a\u0435\u0448\u0435\u0439, \u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043d\u0435 \u0434\u043e\u0436\u0438\u0434\u0430\u044f\u0441\u044c \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043a\u0435\u0448\u0430.<\/li>\n<li>\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0438\u043a\u043e\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u0435\u0448\u0430\u043c\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u0435\u0441\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0435\u0448\u0438 \u0442\u0443\u043f\u044f\u0442, \u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0445.<\/li>\n<li>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0432 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0440\u0435\u0436\u043d\u043e\u0433\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c.<\/li>\n<\/ol>\n<p>  \u0423\u0441\u0443\u0433\u0443\u0431\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u043e\u0439:  <\/p>\n<ol>\n<li>\u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043c\u0435\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/li>\n<li>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438-\u0442\u0430\u043a\u0438 \u043f\u043e \u0441\u0435\u0442\u0438 \u043d\u0430\u0448 \u043e\u0431\u044a\u0435\u043a\u0442, \u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0442\u043c\u0435\u043d\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044e \u043a\u0435\u0448\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u00ab\u043e\u0442\u043c\u0435\u043d\u0443 \u043e\u0442\u043c\u0435\u043d\u044b\u00bb \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439.<\/li>\n<\/ol>\n<p>  \u0415\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u043e, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439:  <\/p>\n<ol>\n<li>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041f\u0440\u0438\u0447\u0435\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u043d\u0430 \u0432\u0441\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<br \/> \n<ul>\n<li>\u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0432\u0441\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435: \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0437\u0430\u043f\u0440\u043e\u0441, \u043e\u0442\u0432\u0435\u0442;<\/li>\n<li>\u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0432\u0441\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043a\u0435\u0448\u0430\u043c\u0438.<\/li>\n<\/ul>\n<\/li>\n<li>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u0438\u043d\u043e\u0440\u043e\u0434\u043d\u044b\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0432 UI-\u043f\u043e\u0442\u043e\u043a\u0435).<\/li>\n<li>\u041d\u0438\u043a\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u043e\u0432 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u043f\u043e\u0442\u043e\u043a\u0438.<\/li>\n<\/ol>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/d5e\/475\/ed0\/d5e475ed0f7e4dd09f1930742033b916.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0412\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0415\u0441\u043b\u0438 \u0443 \u043a\u043e\u0433\u043e-\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043e\u0442\u0432\u0435\u0442, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u044f \u0441 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435\u043c \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u044e\u0441\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c. \u041d\u0443 \u0430 \u043d\u0438\u0436\u0435 \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0441\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435: \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0432 \u043d\u0435\u043c \u0430\u043a\u0446\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0435\u0448\u0435\u0439 \u0438 \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438, \u0430 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0435 \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430\u043c \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u043c.<\/p>\n<h2>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/3c5\/fce\/32c\/3c5fce32c9154c518f5bdf5a681da7b7.png\" \/><\/div>\n<p>  \u041e\u043f\u0438\u0448\u0443 \u0441\u0443\u0442\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e:  <\/p>\n<ol>\n<li><code>UI<\/code>, <code>Mem Cache<\/code>, <code>Disk Cache<\/code>, <code>Network<\/code> \u0441\u0443\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0430\u0448\u0438\u043c \u0441\u0432\u0435\u0436\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c <code>Handler<\/code>.<\/li>\n<li><code>Handler<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0435\u0445\u0438\u0442\u0440\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c:<br \/> \n<ul>\n<li>\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043a\u0435\u0448\u0435\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 <code>Mem Cache<\/code> \u0438 <code>Disk Cache<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0441 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0445\u043e\u0442\u044f \u0431\u044b \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u0435\u0448\u0430, \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0410 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0445\u0430 (\u043a\u0430\u043a \u043d\u0430 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435) \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f.<\/li>\n<li>\u041f\u043e\u0441\u043b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0442 \u043e\u0431\u043e\u0438\u0445 \u043a\u0435\u0448\u0435\u0439 <code>Handler<\/code> \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a <code>Network<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e \u0441\u0435\u0442\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 (<code>connect<\/code>), \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (<code>send<\/code>) \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 (<code>receive<\/code>). \u0422\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f.<\/li>\n<li>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>Network<\/code> \u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0432 \u043e\u0431\u0430 \u043a\u0435\u0448\u0430.<\/li>\n<li>\u041f\u043e\u0441\u043b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043a\u0435\u0448\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 UI-\u043f\u043e\u0442\u043e\u043a.<\/li>\n<\/ul>\n<\/li>\n<li>\u0412 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u0438 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b:<br \/> \n<ul>\n<li>UI-\u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e <code>Handler<\/code> \u0438 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;<\/li>\n<li>\u043e\u0431\u0449\u0438\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>Mem Cache<\/code> \u0438 <code>Disk Cache<\/code>;<\/li>\n<li>\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f <code>Network<\/code>. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043d\u0435 \u0432\u043b\u0438\u044f\u043b\u0430 \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>  \u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u0440\u0430\u043d\u0435\u0435, \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043b\u044f \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438 \u044d\u0442\u043e \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>\/\/ stub: \u0434\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u043a\u0435\u0448 struct DiskCache {    boost::optional&lt;std::string&gt; get(const std::string& key)    {        JLOG(&quot;get: &quot; &lt;&lt; key);        return boost::optional&lt;std::string&gt;();    }        void set(const std::string& key, const std::string& val)    {        JLOG(&quot;set: &quot; &lt;&lt; key &lt;&lt; &quot;;&quot; &lt;&lt; val);    } };  \/\/ \u043a\u0435\u0448 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438: \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 struct MemCache {    boost::optional&lt;std::string&gt; get(const std::string& key)    {       auto it = map.find(key);       return it == map.end()          ? boost::optional&lt;std::string&gt;()          : boost::optional&lt;std::string&gt;(it-&gt;second);    }     void set(const std::string& key, const std::string& val)    {       map[key] = val;    }     private:    std::unordered_map&lt;std::string, std::string&gt; map; };  struct Network {    \/\/ ...    \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e \u0441\u0435\u0442\u0438    std::string get(const std::string& key)    {        net::Socket socket;        JLOG(&quot;connecting&quot;);        socket.connect(address, port);        \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0439\u0442 - \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438        Buffer sz(1, char(key.size()));        socket.write(sz);        \/\/ \u0437\u0430\u0442\u0435\u043c - \u0441\u0442\u0440\u043e\u043a\u0430        socket.write(key);        \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430        socket.read(sz);        Buffer val(size_t(sz[0]), 0);        \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442        socket.read(val);        JLOG(&quot;val received&quot;);        return val;    }  private:     std::string address;     int port;     \/\/ ... };  \/\/ UI-\u043e\u0431\u044a\u0435\u043a\u0442: \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 UI struct UI : IScheduler {    void schedule(Handler handler)    {        \/\/ \u0437\u0430\u043f\u0443\u0441\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 UI-\u043f\u043e\u0442\u043e\u043a\u0435        \/\/ ...    }     void handleResult(const std::string& key, const std::string& val)    {        TLOG(&quot;UI result inside UI thread: &quot; &lt;&lt; key &lt;&lt; &quot;;&quot; &lt;&lt; val);        \/\/ TODO: add some actions    } }; <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432\u0441\u0435 UI-\u0444\u0440\u0435\u0439\u0432\u043e\u0440\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432 UI-\u043f\u043e\u0442\u043e\u043a\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 Android: <code>Activity.runOnUiThread<\/code>, Ultimate++: <code>PostCallback<\/code>, Qt: \u0447\u0435\u0440\u0435\u0437 signal-slot \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c). \u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>UI::schedule<\/code>.<\/p>\n<p>  \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u0445\u043e\u0437\u044f\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435:<\/p>\n<pre><code>\/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 ThreadPool cpu(3, &quot;cpu&quot;); \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 ThreadPool net(2, &quot;net&quot;);  \/\/ \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441 \u0434\u0438\u0441\u043a\u043e\u043c Alone diskStorage(cpu, &quot;disk storage&quot;); \/\/ \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e Alone memStorage(cpu, &quot;mem storage&quot;);  \/\/ \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e scheduler&lt;DefaultTag&gt;().attach(cpu); \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043a \u0441\u0435\u0442\u0435\u0432\u043e\u043c\u0443 \u043f\u0443\u043b\u0443 service&lt;NetworkTag&gt;().attach(net); \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u043a \u043e\u0431\u0449\u0435\u043c\u0443 \u043f\u0443\u043b\u0443 service&lt;TimeoutTag&gt;().attach(cpu);  \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043a \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u043c\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 portal&lt;DiskCache&gt;().attach(diskStorage); \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 portal&lt;MemCache&gt;().attach(memStorage); \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043a \u0441\u0435\u0442\u0435\u0432\u043e\u043c\u0443 \u043f\u0443\u043b\u0443 portal&lt;Network&gt;().attach(net);  UI& ui = single&lt;UI&gt;(); \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 UI-\u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043a UI-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 portal&lt;UI&gt;().attach(ui); <\/code><\/pre>\n<p>  \u0412 UI-\u043f\u043e\u0442\u043e\u043a\u0435 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c:<\/p>\n<pre><code>go([key] {    \/\/ timeout \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439: 1\u0441=1000 \u043c\u0441    Timeout t(1000);    std::string val;    \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437 \u043a\u0435\u0448\u0435\u0439 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e    boost::optional&lt;std::string&gt; result = goAnyResult&lt;std::string&gt;({        [&key] {            return portal&lt;DiskCache&gt;()-&gt;get(key);        }, [&key] {            return portal&lt;MemCache&gt;()-&gt;get(key);        }    });    if (result)    {        \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0439\u0434\u0435\u043d        val = std::move(*result);        JLOG(&quot;cache val: &quot; &lt;&lt; val);    }    else    {        \/\/ \u043a\u0435\u0448\u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430        \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e \u0441\u0435\u0442\u0438        {            \/\/ \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443: 0.5\u0441=500 \u043c\u0441            Timeout tNet(500);            val = portal&lt;Network&gt;()-&gt;get(key);        }        JLOG(&quot;net val: &quot; &lt;&lt; val);        \/\/ \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0431\u043b\u043e\u043a\u0430        \/\/ \u043e\u0442\u043c\u0435\u043d\u0430 (\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b) \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u044b        EventsGuard guard;        \/\/ \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043e\u0431\u0430 \u043a\u0435\u0448\u0430        goWait({            [&key, &val] {                portal&lt;DiskCache&gt;()-&gt;set(key, val);            }, [&key, &val] {                portal&lt;MemCache&gt;()-&gt;set(key, val);            }        });        JLOG(&quot;cache updated&quot;);    }    \/\/ \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 UI \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442    portal&lt;UI&gt;()-&gt;handleResult(key, val); }); <\/code><\/pre>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/3d1\/3b7\/f4a\/3d13b7f4aa4e4c5fa749c545b3b19934.jpeg\" width=\"640\" \/><\/div>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432<\/h2>\n<p>  \u041a\u0430\u043a \u0437\u0430\u043c\u0435\u0442\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c, \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043d\u0435\u043c\u0430\u043b\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432, \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0433\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u0414\u0443\u043c\u0430\u044e, \u044d\u0442\u043e \u043f\u0440\u043e\u044f\u0441\u043d\u0438\u0442, \u0447\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u044b, \u043a\u0430\u043a \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f\u0445.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/8af\/b5b\/745\/8afb5b745a4c4f288f2882aab384370e.jpeg\" width=\"640\" \/><\/div>\n<h2>\u041e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/h2>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u2013 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432.<\/p>\n<h4>goWait: \u0437\u0430\u043f\u0443\u0441\u043a \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u0437\u0430\u0442\u0440\u0430\u0432\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0435\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>void goWait(Handler); <\/code><\/pre>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435. \u041d\u043e \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445 \u043d\u0430\u0441 \u044d\u0442\u043e \u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0438\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<pre><code>void goWait(Handler handler) {     deferProceed([&handler](Handler proceed) {         go([proceed, &handler] { \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443             handler();             proceed(); \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b         });     }); } <\/code><\/pre>\n<p>  \u041e\u043f\u0438\u0448\u0443 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0447\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u041d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 goWait \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0432 \u043d\u043e\u0432\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435. \u0414\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>deferProceed<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>typedef std::function&lt;void(Handler)&gt; ProceedHandler;  void deferProceed(ProceedHandler proceed) {     auto& coro = currentCoro();     defer([&coro, proceed] {         proceed([&coro] { coro.resume(); });     }); } <\/code><\/pre>\n<p>  \u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f? \u041e\u043d\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 defer \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f (\u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>defer<\/code> \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043c\u043e\u0435\u0439 <a href=\"http:\/\/habrahabr.ru\/post\/201826\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>), \u0430 \u0438\u043c\u0435\u043d\u043d\u043e: \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0435 <code>Handler<\/code>, \u0430 <code>ProceedHandler<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>Handler<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0441\u0430\u043c <code>proceed<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0432 \u0441\u0432\u043e\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>coro.resume()<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438, \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441 <code>proceed<\/code>-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c.<\/p>\n<p>  \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>goWait<\/code>. \u0418\u0442\u0430\u043a, \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>deferProceed<\/code> \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <code>proceed<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0437\u0432\u0430\u0442\u044c \u043f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 <code>handler<\/code>. \u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 \u043d\u0435\u0439 \u043d\u0430\u0448 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <code>handler<\/code>, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0435\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0437\u0432\u0430\u0442\u044c proceed, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u043f\u043e\u0437\u043e\u0432\u0435\u0442 <code>coro.resume()<\/code>, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0432 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>  \u042d\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0431\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u0442\u043e\u043a\u0430: \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 <code>goWait<\/code> \u043c\u044b \u043a\u0430\u043a \u0431\u044b \u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0430 \u043f\u0430\u0443\u0437\u0443, \u0430 \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u043d\u0438 \u0432 \u0447\u0435\u043c \u043d\u0435 \u0431\u044b\u0432\u0430\u043b\u043e.<\/p>\n<h4>goWait: \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0438\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0446\u0435\u043b\u0443\u044e \u043f\u0430\u0447\u043a\u0443 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0438\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>void goWait(std::initializer_list&lt;Handler&gt; handlers); <\/code><\/pre>\n<p>  \u041d\u0430 \u0432\u0445\u043e\u0434 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0432 \u0441\u0432\u043e\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u0432\u0441\u044f\u043a\u0438\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b \u0438 condition variables (\u0438 \u0442\u0430\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u0435-\u043a\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u0442!), \u043d\u043e \u043d\u0430\u043c \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f (\u0441\u043c. \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0443\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0418\u0434\u0435\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>proceed<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e \u0441\u0432\u043e\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a, \u0438 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0438\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c: \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438, \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0437\u0432\u0430\u0442\u044c proceed, \u043d\u043e \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438. \u0412\u0441\u0435 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>void goWait(std::initializer_list&lt;Handler&gt; handlers) {     deferProceed([&handlers](Handler proceed) {         std::shared_ptr&lt;void&gt; proceeder(nullptr, [proceed](void*) { proceed(); });         for (const auto& handler: handlers)         {             go([proceeder, &handler] {                 handler();             });         }     }); } <\/code><\/pre>\n<p>  \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0442\u0430\u0440\u044b\u0439 \u0434\u043e\u0431\u0440\u044b\u0439 <code>deferProceed<\/code>, \u0430 \u0432\u043e\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0441\u043f\u0440\u044f\u0442\u0430\u043d\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043c\u0430\u0433\u0438\u044f. \u041c\u0430\u043b\u043e \u043a\u0442\u043e \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 <code>shared_ptr<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u043e \u0438 <code>deleter<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043d\u0435 <code>delete ptr<\/code>, \u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0442\u0443\u0434\u0430-\u0442\u043e \u043c\u044b \u0438 \u0437\u0430\u0441\u0443\u043d\u0435\u043c \u0432\u044b\u0437\u043e\u0432 proceed, \u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0441\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0442\u0443\u0434\u0430 \u043a\u043b\u0430\u0434\u0435\u043c \u00ab\u043d\u0438\u0447\u0442\u043e\u00bb \u2013 <code>nullptr<\/code>. \u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e: \u0432 \u0446\u0438\u043a\u043b\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0445 \u0432 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445. \u0422\u0443\u0442 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u044e\u0430\u043d\u0441: \u043c\u044b \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u043d\u0430\u0448 <code>proceeder<\/code>, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u0435\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0433\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441\u0441\u044b\u043b\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0438 <code>shared_ptr<\/code>. \u041f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b <code>handler<\/code> \u043d\u0430\u0448\u0430 \u043b\u044f\u043c\u0431\u0434\u0430 \u0441 \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u043c proceeder \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430. \u041a\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e \u043d\u0443\u043b\u044f \u0438 \u0443\u0434\u0430\u043b\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>proceeder<\/code>, \u0442\u043e\u0442 \u0438 \u043f\u043e\u0437\u043e\u0432\u0435\u0442 <code>deleter<\/code> \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0433\u043e <code>shared_ptr<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 <code>coro.proceed()<\/code>.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/0f3\/b52\/9a6\/0f3b529a67d147f28d063863cb2e45f0.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u044f\u0441\u043d\u043e\u0441\u0442\u0438 \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u0432\u0443\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/a7d\/edb\/d20\/a7dedbd20ef64713be7cca56c0f7924e.png\" \/><\/div>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440: \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e-\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438<\/h4>\n<p>  \u0414\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043d\u0430 \u043d\u0430\u0441 \u043d\u0430\u0448\u043b\u0430 \u0431\u043b\u0430\u0436\u044c \u0438 \u043d\u0430\u043c \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u044f\u0434 \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u041d\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c:<\/p>\n<pre><code>int fibo (int v) {     if (v &lt; 2)         return v;     int v1, v2;     goWait({         [v, &v1] { v1 = fibo(v-1); },         [v, &v2] { v2 = fibo(v-2); }     });     return v1 + v2; } <\/code><\/pre>\n<p>  \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0435\u043a\u0430: \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>fibo<\/code> \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u0432\u043e\u0435\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435.<\/p>\n<h4>Waiter: \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0438\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0427\u0430\u0441\u0442\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043d\u043e \u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0435\u043b\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f. \u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e \u0445\u043e\u0434\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u0433\u0440\u0443\u043f\u043f\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u044b\u043c \u0446\u0435\u043b\u044b\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 <code>Waiter<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c:<\/p>\n<pre><code>struct Waiter {     Waiter& go(Handler);     void wait(); }; <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430:  <\/p>\n<ol>\n<li>go: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a;<\/li>\n<li>wait: \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.<\/li>\n<\/ol>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0436\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0437\u0430 \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Waiter<\/code>.<\/p>\n<p>  \u0418\u0434\u0435\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0436\u0435: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c <code>proceeder<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b \u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0448\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044c: \u0442\u0435\u043f\u0435\u0440\u044c <code>proceeder<\/code> \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c <code>Waiter<\/code>. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>wait<\/code> \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u043e\u043f\u0438\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c <code>Waiter<\/code>. \u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<pre><code>void Waiter::wait() {     if (proceeder.unique())     {         \/\/ \u0442\u043e\u043b\u044c\u043a\u043e Waiter \u0432\u043b\u0430\u0434\u0435\u0435\u0442 proceeder =&gt;         JLOG(&quot;everything done, nothing to do&quot;);         return;     }     defer([this] {         \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c proceeder \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u043d\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b         auto toDestroy = std::move(proceeder);         \/\/ \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 proceeder \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u0437\u0434\u0435\u0441\u044c,         \/\/ \u043b\u0438\u0431\u043e \u0432 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430     });     \/\/ proceeder \u0432 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0435\u043d,     \/\/ \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0435\u0433\u043e \u0441\u043d\u043e\u0432\u0430 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f     init0(); } <\/code><\/pre>\n<p>  \u0418 \u043e\u043f\u044f\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c! \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u044d\u0442\u043e <code>shared_ptr<\/code>. \u0410\u043c\u0438\u043d\u044c!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/290\/eeb\/977\/290eeb9774654cf4831a411a566219b2.jpeg\" width=\"640\" \/><\/div>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440: \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e-\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438<\/h4>\n<p>  \u0414\u043b\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0439 \u0431\u043b\u0430\u0436\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>Waiter<\/code>:<\/p>\n<pre><code>int fibo (int v) {     if (v &lt; 2)         return v;     int v1;     Waiter w;     w.go([v, &v1] { v1 = fibo(v-1); });     int v2 = fibo(v-2);     w.wait();     return v1 + v2; } <\/code><\/pre>\n<p>  \u0415\u0449\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442:<\/p>\n<pre><code>int fibo (int v) {     if (v &lt; 2)         return v;     int v1, v2;     Waiter()         .go([v, &v1] { v1 = fibo (v-1); })         .go([v, &v2] { v2 = fibo (v-2); })         .wait();     return v1 + v2; } <\/code><\/pre>\n<p>  \u0412\u044b\u0431\u0438\u0440\u0430\u0439 \u043d\u0435 \u0445\u043e\u0447\u0443.<\/p>\n<h4>goAnyWait: \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e\u0439<\/h4>\n<p>  \u041f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u041d\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u043e\u0432\u043d\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f:<\/p>\n<pre><code>size_t goAnyWait(std::initializer_list&lt;Handler&gt; handlers); <\/code><\/pre>\n<p>  \u041d\u0430 \u0432\u0445\u043e\u0434 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u2013 \u043d\u043e\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 \u043f\u043e\u0434\u0445\u043e\u0434. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0435 <code>void* ptr == nullptr<\/code>, \u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0441\u0435\u0431\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0439 \u0441\u0447\u0435\u0442\u0447\u0438\u043a <code>counter<\/code>. \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u043d \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>0<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a. \u0418 \u0435\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 <code>0<\/code> \u0434\u043e <code>1<\/code>, \u0442\u043e \u043e\u043d \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>proceed()<\/code>:<\/p>\n<pre><code>size_t goAnyWait(std::initializer_list&lt;Handler&gt; handlers) {    VERIFY(handlers.size() &gt;= 1, &quot;Handlers amount must be positive&quot;);     size_t index = static_cast&lt;size_t&gt;(-1);    deferProceed([&handlers, &index](Handler proceed) {       std::shared_ptr&lt;std::atomic&lt;int&gt;&gt; counter =          std::make_shared&lt;std::atomic&lt;int&gt;&gt;();       size_t i = 0;       for (const auto& handler: handlers)       {          go([counter, proceed, &handler, i, &index] {             handler();             if (++ *counter == 1)             {                \/\/ \u0430\u0433\u0430, \u043f\u043e\u043f\u0430\u043b\u0441\u044f!                index = i;                proceed();             }          });          ++ i;       }    });    VERIFY(index &lt; handlers.size(), &quot;Incorrect index returned&quot;);    return index; } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043d\u0435\u0442\u0440\u0443\u0434\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u044d\u0442\u043e\u0442 \u0444\u043e\u043a\u0443\u0441 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0434\u0432\u0443\u0445, \u0442\u0440\u0435\u0445 \u0438 \u0431\u043e\u043b\u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.<\/p>\n<h4>goAnyResult: \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430<\/h4>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0432\u043a\u0443\u0441\u043d\u043e\u043c\u0443, \u0447\u0442\u043e, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u0410 \u0438\u043c\u0435\u043d\u043d\u043e: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043d\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0422\u043e \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u0432\u043e\u044e \u043e\u043d \u0434\u043e\u0434\u0435\u043b\u0430\u0435\u0442, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043a\u0430\u0436\u0435\u0442: \u00ab\u041d\u0443 \u043d\u0435 \u0448\u043c\u043e\u0433\u043b\u0430 \u044f, \u043d\u0435 \u0448\u043c\u043e\u0433\u043b\u0430\u00bb.<\/p>\n<p>  \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c. \u0412\u0435\u0434\u044c \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443, \u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u0442\u0430\u043a \u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f, \u0432\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u0441\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043b\u0438 \u043c\u044b \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0430 \u0432\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u00ab\u043f\u0443\u0441\u0442\u043e\u0439\u00bb \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0414\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0443\u0441\u0442\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>boost::optional&lt;T_result&gt;<\/code>, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c <code>goAnyResult<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c \u0432\u043e\u0442 \u043d\u0435\u0437\u0430\u043c\u044b\u0441\u043b\u043e\u0432\u0430\u0442\u044b\u043c \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u043c:<\/p>\n<pre><code>template&lt;typename T_result&gt; boost::optional&lt;T_result&gt; goAnyResult(    std::initializer_list&lt;       std::function&lt;          boost::optional&lt;T_result&gt;()       &gt;    &gt; handlers) <\/code><\/pre>\n<p>  \u041d\u0438\u0447\u0435\u0433\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0433\u043e \u0442\u0443\u0442 \u043d\u0435\u0442: \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043d\u0430\u0448 <code>T_result<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443:<\/p>\n<pre><code>boost::optional&lt;T_result&gt; handler(); <\/code><\/pre>\n<p>  \u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u043c \u043b\u0438\u0448\u044c \u0441\u043b\u0435\u0433\u043a\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439, \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0435\u0433\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c <code>counter<\/code>, \u0438 \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u0435\u0433\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 <code>1<\/code>, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u00ab\u043f\u0443\u0441\u0442\u043e\u0435\u00bb \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0438\u043a\u0442\u043e \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u043c\u043e\u0433 \u043f\u0435\u0440\u0435\u0434\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f <code>counter<\/code> \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0446\u0435\u043b\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>Counter<\/code>:<\/p>\n<pre><code>template&lt;typename T_result&gt; boost::optional&lt;T_result&gt; goAnyResult(    std::initializer_list&lt;       std::function&lt;          boost::optional&lt;T_result&gt;()       &gt;    &gt; handlers) {     typedef boost::optional&lt;T_result&gt; Result;     typedef std::function&lt;void(Result&&)&gt; ResultHandler;          struct Counter     {         Counter(ResultHandler proceed_) : proceed(std::move(proceed_)) {}         ~Counter()         {             tryProceed(Result()); \/\/ \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u043f\u043e-\u043b\u044e\u0431\u043e\u043c\u0443         }                  void tryProceed(Result&& result)         {             if (++ counter == 1)                 proceed(std::move(result));         }              private:         std::atomic&lt;int&gt; counter;         ResultHandler proceed;     };      Result result;     deferProceed([&handlers, &result](Handler proceed) {         std::shared_ptr&lt;Counter&gt; counter = std::make_shared&lt;Counter&gt;(             [&result, proceed](Result&& res) {                 result = std::move(res);                 proceed();             }         );          for (const auto& handler: handlers)         {             go([counter, &handler] {                 Result result = handler();                 if (result) \/\/ \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430                     counter-&gt;tryProceed(std::move(result));             });         }     });     return result; } <\/code><\/pre>\n<p>  \u0418\u043d\u0442\u0440\u0438\u0433\u0430 \u0442\u0443\u0442 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>std::move<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 <code>tryProceed<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f. \u0410 \u0432\u0441\u0435 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e <code>std::move<\/code> \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u0442\u0430\u043a\u043e\u0432\u043e\u0435, \u043a\u0430\u043a \u0431\u044b \u043a\u043e\u043c\u0443-\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0438 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c. \u042d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c cast-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0434 \u0441\u0441\u044b\u043b\u043a\u0430\u043c\u0438.<\/p>\n<p>  \u0421 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f\u043c\u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u043c \u0438 \u043f\u0443\u043b\u0430\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<h2>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043f\u0443\u043b\u044b, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<h4>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/h4>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043e\u0441\u043d\u043e\u0432, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0434\u0435\u0441\u0435\u0440\u0442\u0443.<br \/>  \u0412\u0432\u0435\u0434\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430:<\/p>\n<pre><code>struct IScheduler : IObject {     virtual void schedule(Handler handler) = 0; }; <\/code><\/pre>\n<p>  \u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u2013 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043d\u0435\u0442 \u043d\u0438 \u043e\u0442\u043c\u0435\u043d, \u043d\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432, \u043d\u0438 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u0440\u0438\u0441\u0442\u0430\u043b\u044c\u043d\u043e \u0447\u0438\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0441\u0442\u044b\u043a\u043e\u0432\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 (\u0441\u0440. \u0441 <a href=\"http:\/\/doc.akka.io\/docs\/akka\/2.1.4\/scala\/scheduler.html\">[2]<\/a>: \u0442\u0443\u0442 \u0442\u0435\u0431\u0435 \u0438 \u043e\u0442\u043c\u0435\u043d\u0430, \u0438 \u0430\u043a\u0442\u043e\u0440\u044b, \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438, \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0441\u043a\u0440\u0435\u0449\u0438\u0432\u0430\u0442\u044c \u0441 UI-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u043c\u0438).<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/353\/403\/d24\/353403d2484f420a86459e652e7c096e.jpeg\" width=\"640\" \/><\/div>\n<h4>\u041f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432<\/h4>\n<p>  \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430:<\/p>\n<pre><code>typedef boost::asio::io_service IoService; struct IService : IObject {     virtual IoService& ioService() = 0; };  struct ThreadPool : IScheduler, IService {     ThreadPool(size_t threadCount);          void schedule(Handler handler)     {         service.post(std::move(handler));     }  private:     IoService& ioService();      std::unique_ptr&lt;boost::asio::io_service::work&gt; work;     boost::asio::io_service service;     std::vector&lt;std::thread&gt; threads; }; <\/code><\/pre>\n<p>  \u0427\u0442\u043e \u043c\u044b \u0442\u0443\u0442 \u0438\u043c\u0435\u0435\u043c?  <\/p>\n<ol>\n<li>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u0434\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/li>\n<li>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>boost::asio::io_service::post<\/code>.<\/li>\n<li>\u0427\u043b\u0435\u043d \u043a\u043b\u0430\u0441\u0441\u0430 <code>work<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0446\u0438\u043a\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0439 <code>io_service<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u0441\u0445\u043b\u043e\u043f\u043d\u0443\u0442\u0441\u044f.<\/li>\n<li>\u041c\u0430\u0441\u0441\u0438\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/li>\n<\/ol>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 (\u043f\u0440\u0438\u0447\u0435\u043c \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e) \u043d\u0435\u043a\u0438\u0439 \u043c\u0443\u0442\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IService<\/code> \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>ioService<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>IoService<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0441\u0442\u044c <code>boost::asio::io_service<\/code>. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u0441\u0435 \u044d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043d\u043e \u044f \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0432 \u0447\u0435\u043c \u0442\u0443\u0442 \u0444\u0438\u0448\u043a\u0430.<\/p>\n<p>  \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0435\u0442\u0435\u0432\u044b\u043c\u0438 \u0441\u043e\u043a\u0435\u0442\u0430\u043c\u0438 \u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430\u043c\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430. \u042d\u0442\u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0441\u043f\u0440\u044f\u0442\u0430\u043d \u0432\u043d\u0443\u0442\u0440\u0438 <code>boost::asio::io_service<\/code>. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0434\u043e\u043b\u0436\u043d\u044b \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0443 <code>boost::asio::io_service<\/code>. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u043e\u043c\u0443 \u043a\u043b\u0430\u0441\u0441\u0443, \u044f \u0432\u0432\u0435\u043b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IService<\/code>, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0442\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434 \u0441\u0434\u0435\u043b\u0430\u043d \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c. \u042d\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430\u0440\u0443\u0436\u0443, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c <code>ThreadPool<\/code> \u0432 <code>IService<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0437\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u0431\u044b\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0440\u0443\u0436\u0435\u0441\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u041d\u043e \u044f \u043d\u0435 \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0440\u0442\u0438\u0442\u044c <code>ThreadPool<\/code> \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043b, \u0447\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u043e\u0439 \u0437\u0430 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044e.<\/p>\n<h4>\u041a\u043b\u0430\u0441\u0441 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h4>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043d\u0430\u0441\u0442\u0430\u043b\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432\u0432\u0435\u0441\u0442\u0438 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u043d\u0430\u0434 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438. \u041d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u043d \u0431\u0443\u0434\u0435\u0442, \u043a\u0430\u043a \u044d\u0442\u043e \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, <code>Journey<\/code> (\u043f\u043e\u0447\u0435\u043c\u0443 \u0442\u0430\u043a, \u0431\u0443\u0434\u0435\u0442 \u044f\u0441\u043d\u043e \u043f\u043e\u0437\u0436\u0435):<\/p>\n<pre><code>struct Journey {     void proceed();     Handler proceedHandler();     void defer(Handler handler);     void deferProceed(ProceedHandler proceed);     static void create(Handler handler, mt::IScheduler& s);  private:     Journey(mt::IScheduler& s);      struct CoroGuard     {         CoroGuard(Journey& j_) : j(j_)  { j.onEnter0();   }         ~CoroGuard()                    { j.onExit0();    }                  coro::Coro* operator-&gt;()        { return &j.coro; }     private:         Journey& j;     };          void start0(Handler handler);     void schedule0(Handler handler);     CoroGuard guardedCoro0();     void proceed0();     void onEnter0();     void onExit0();          mt::IScheduler* sched;     coro::Coro coro;     Handler deferHandler; }; <\/code><\/pre>\n<p>  \u0427\u0442\u043e \u0442\u0443\u0442 \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u0432 \u0433\u043b\u0430\u0437\u0430?  <\/p>\n<ul>\n<li>\u041f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440. \u041e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>create<\/code>.<\/li>\n<li><code>Journey<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a <code>sched<\/code>, \u0441\u0430\u043c\u0443 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 <code>coro<\/code> \u0438 <code>deferHandler<\/code>-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 <code>defer<\/code>.<\/li>\n<li><code>CoroGuard<\/code> \u2013 \u043f\u0440\u043e\u043a\u0441\u0438-\u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f <code>onEnter0<\/code> \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u043d\u0435\u0435 \u0438 <code>onExit0<\/code> \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435.<\/li>\n<\/ul>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<pre><code>void Journey::schedule0(Handler handler) {     VERIFY(sched != nullptr, &quot;Scheduler must be set in journey&quot;);     sched-&gt;schedule(std::move(handler));  }  void Journey::proceed0() {     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0437\u0430\u0449\u0438\u0442\u043d\u0438\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     guardedCoro0()-&gt;resume();  }  Journey::CoroGuard Journey::guardedCoro0() {     return CoroGuard(*this); }  \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 void Journey::proceed() {     schedule0([this] {         proceed0();     }); }  \/\/ \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 Handler Journey::proceedHandler() {     return [this] {         proceed();     }; }  \/\/ \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u043e\u0432\u043e\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \/\/ \u0441\u043c. \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0443 1 void Journey::start0(Handler handler) {     schedule0([handler, this] {         \/\/ \u0441\u043d\u043e\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0437\u0430\u0449\u0438\u0442\u043d\u0438\u043a         guardedCoro0()-&gt;start([handler] {             JLOG(&quot;started&quot;);             \/\/ \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f             try             {                 handler();             }             catch (std::exception& e)             {                 (void) e;                 JLOG(&quot;exception in coro: &quot; &lt;&lt; e.what());             }             JLOG(&quot;ended&quot;);         });     }); } <\/code><\/pre>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 defer:<\/p>\n<pre><code>void Journey::defer(Handler handler) {     \/\/ \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a     deferHandler = handler;     \/\/ \u0438 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     coro::yield(); }  \/\/ deferProceed, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 void Journey::deferProceed(ProceedHandler proceed) {     defer([this, proceed] {         proceed(proceedHandler());     }); } <\/code><\/pre>\n<p>  \u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e! \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u0434\u0435 \u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0448\u0438 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 <code>deferHandler<\/code>.<\/p>\n<pre><code>TLS Journey* t_journey = nullptr;  void Journey::onEnter0() {     t_journey = this; }  \/\/ \u0441\u043c. \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0443 2 void Journey::onExit0() {     if (deferHandler == nullptr)     {         \/\/ \u043d\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 =&gt; \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b, \u043c\u043e\u0436\u043d\u043e \u0441\u0430\u043c\u043e\u043b\u0438\u043a\u0432\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f         delete this;     }     else     {         \/\/ \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435         deferHandler();         deferHandler = nullptr;     }     \/\/ \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432\u043d\u0435 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     t_journey = nullptr; } <\/code><\/pre>\n<p>  \u041d\u0443 \u0438 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>create<\/code>:<\/p>\n<pre><code>void Journey::create(Handler handler, mt::IScheduler& s) {     (new Journey(s))-&gt;start0(std::move(handler)); } <\/code><\/pre>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>Journey<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u043d \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u0435\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0430\u0441\u0441. \u041d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441\u2026<\/p>\n<h4>\u0422\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f<\/h4>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043a\u043b\u0443\u0431\u043d\u0438\u0447\u043a\u0435! \u0422\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f\u2026 \u0420\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043f\u0440\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u0410 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u043d\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0438 \u043f\u043e\u0441\u043c\u0430\u043a\u043e\u0432\u0430\u0442\u044c. \u0412\u0435\u0434\u044c \u044d\u0442\u043e \u0436 \u043a\u043b\u0443\u0431\u043d\u0438\u0447\u043a\u0430!<\/p>\n<p>  \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435 \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>void Journey::teleport(mt::IScheduler& s) {     if (&s == sched)     {         JLOG(&quot;the same destination, skipping teleport &lt;-&gt; &quot; &lt;&lt; s.name());         return;     }     JLOG(&quot;teleport &quot; &lt;&lt; sched-&gt;name() &lt;&lt; &quot; -&gt; &quot; &lt;&lt; s.name());     sched = &s;     defer(proceedHandler()); } <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0435 \u0432\u0435\u0449\u0438:  <\/p>\n<ol>\n<li>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043e\u0442 \u0442\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0430\u043b\u0438 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u043e\u043d \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043d\u0438\u043c, \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438 \u0442\u0430\u043a \u043d\u0443\u0436\u043d\u044b\u0439.<\/li>\n<li>\u0415\u0441\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043c\u0435\u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u0435\u0440\u0435\u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443: <code>defer<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u044b\u0445\u043e\u0434\u0443 \u0438\u0437 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u0441\u043a\u043e\u0440\u0435\u0439\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0445\u043e\u0434 \u0432 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0443\u0436\u0435 \u0432 \u043d\u043e\u0432\u043e\u043c \u043f\u0443\u043b\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/li>\n<\/ol>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/bc3\/1c4\/88a\/bc31c488a5f947c9a5c1e2fc08044c79.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0421\u0445\u0435\u043c\u0430 \u043d\u0438\u0436\u0435 \u043f\u043e\u044f\u0441\u043d\u044f\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441 <code>Scheduler<\/code>\/<code>Thread<\/code> \u043d\u0430 <code>Scheduler2<\/code>\/<code>Thread2<\/code>:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/3c6\/1e4\/d99\/3c61e4d99f0640069ce25687bbce25d9.png\" \/><\/div>\n<p>  \u0427\u0442\u043e \u044d\u0442\u043e \u043d\u0430\u043c \u0434\u0430\u0435\u0442? \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0434\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043f\u0443\u043b\u0430\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435, \u0432\u043e\u043e\u0431\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u0435\u0436\u0434\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u043c\u0438. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 UI-\u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0447\u0442\u043e\u0431\u044b UI, \u0447\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043d\u0435 \u0442\u0443\u043f\u0438\u043b:<\/p>\n<pre><code>auto result = someCalculations(); teleport(uiScheduler); showResult(result); teleport(calcScheduler); auto newResult = continueSmartCalculations(result); teleport(uiScheduler); updateResult(newResult); \/\/\u2026 <\/code><\/pre>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 UI, \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u0438 \u0432\u0441\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 UI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0422\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u0438\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0445\u043e\u0434\u0438\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438\u043b\u0438 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u2013 \u0432 \u043e\u0431\u0449\u0435\u043c, \u0432 \u043b\u044e\u0431\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430. <\/p>\n<h4>\u041f\u043e\u0440\u0442\u0430\u043b\u044b<\/h4>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/965\/61e\/91c\/96561e91cd824fc4aca362cf73d06230.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0432\u0438\u0448\u0435\u043d\u043a\u0435. \u042f \u0431\u044b \u0434\u0430\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u043b, \u043a \u0441\u043b\u0430\u0434\u043a\u043e\u0439 \u0438 \u0441\u043e\u0447\u043d\u043e\u0439 \u0447\u0435\u0440\u0435\u0448\u0435\u043d\u043a\u0435. \u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0443\u0441\u043f\u0435\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f UI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432 UI-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u0440\u0442\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f.<\/p>\n<pre><code>struct Portal {     Portal(mt::IScheduler& destination) :         source(journey().scheduler())     {         JLOG(&quot;creating portal &quot; &lt;&lt; source.name() &lt;&lt; &quot; &lt;=&gt; &quot; &lt;&lt; destination.name());         teleport(destination);     }          ~Portal()     {         teleport(source);     }  private:     mt::IScheduler& source; }; <\/code><\/pre>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043c\u044b \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a (\u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b), \u0430 \u0437\u0430\u0442\u0435\u043c \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0412 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a.<\/p>\n<p>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u0430\u043a\u043e\u0439 RAII-\u0438\u0434\u0438\u043e\u043c\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u044c\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u0430\u043c, \u0433\u0434\u0435 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u044f\u0436\u0435\u043b\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432 UI-\u043f\u043e\u0442\u043e\u043a\u0435 \u043b\u0438\u0431\u043e \u0432 \u0441\u0435\u0442\u0435\u0432\u043e\u043c \u043f\u0443\u043b\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432), \u0432\u0441\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>ThreadPool tp1(1, &quot;tp1&quot;); ThreadPool tp2(1, &quot;tp2&quot;);  go([&tp2] {     Portal p(tp2);     JLOG(&quot;throwing exception&quot;);     throw std::runtime_error(&quot;exception occur&quot;); }, tp1); <\/code><\/pre>\n<p>  \u0421\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0432 tp1, \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0440\u0442\u0430\u043b \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432 tp2. \u041f\u043e\u0441\u043b\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043f\u043e\u0440\u0442\u0430\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043c\u043e\u0440\u0430\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0441\u043a\u0440\u0443\u0442\u043a\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0432 tp1 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0440\u0430\u0441\u043a\u0440\u0443\u0442\u043a\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0438 \u0431\u0435\u0437 \u0421\u041c\u0421!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/4a6\/ed7\/adf\/4a6ed7adf9394d12a104f0eb740e36b7.gif\" width=\"640\" \/><\/div>\n<p>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0435\u0449\u0435 \u0431\u043e\u043b\u0435\u0435 \u0443\u0441\u0443\u0433\u0443\u0431\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432 (\u0445\u043e\u0442\u044f, \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043a\u0443\u0434\u0430 \u0443\u0436), \u043d\u0430\u0432\u0435\u0440\u043d\u0435\u043c:<\/p>\n<pre><code>struct Scheduler {     Scheduler();          void attach(mt::IScheduler& s)     {         scheduler = &s;     }      void detach()     {         scheduler = nullptr;     }      operator mt::IScheduler&() const     {         VERIFY(scheduler != nullptr, &quot;Scheduler is not attached&quot;);         return *scheduler;     }  private:     mt::IScheduler* scheduler; };  struct DefaultTag;  template&lt;typename T_tag&gt; Scheduler& scheduler() {     return single&lt;Scheduler, T_tag&gt;(); }   template&lt;typename T&gt; struct WithPortal : Scheduler {     struct Access : Portal     {         Access(Scheduler& s) : Portal(s) {}         T* operator-&gt;()             { return &single&lt;T&gt;(); }     };          Access operator-&gt;()             { return *this; } };  template&lt;typename T&gt; WithPortal&lt;T&gt;& portal() {     return single&lt;WithPortal&lt;T&gt;&gt;(); } <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0430\u043b\u044b \u043a \u043a\u043b\u0430\u0441\u0441\u0430\u043c, \u043a\u0430\u043a \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/p>\n<pre><code>ThreadPool tp1(1, &quot;tp1&quot;); ThreadPool tp2(1, &quot;tp2&quot;);  struct X {     void op() {} };  portal&lt;X&gt;().attach(tp2); go([] {     portal&lt;X&gt;()-&gt;op(); }, tp1); <\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043b\u0438 \u043f\u043e\u0440\u0442\u0430\u043b <code>X<\/code> \u043a \u043f\u0443\u043b\u0443 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 tp2. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <code>X<\/code> (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 return <code>&single&lt;T&gt;()<\/code>) \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043d\u0430\u043c \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432. <b>\u041d\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>Journey<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0442\u0443\u0434\u0430-\u0441\u044e\u0434\u0430, \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044f\u0441\u044c \u0441\u043a\u0432\u043e\u0437\u044c \u043f\u043e\u0440\u0442\u0430\u043b\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432!<\/b><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/bc9\/3ec\/7ae\/bc93ec7aeb214ce3a08912040cb1c0ba.jpeg\" width=\"640\" \/><\/div>\n<p>  \u042d\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0442\u0435\u043c, \u0433\u0434\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0430\u0448\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u041a\u043b\u0430\u0441\u0441\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0437\u0430\u0431\u043e\u0442\u044f\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u044f\u0441\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u043c\u043e\u0449\u044c \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u0439 \u0438 \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432.<\/p>\n<h4>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b<\/h4>\n<p>  \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b. \u041e\u043d\u043e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e: \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043e\u043d \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0430\u0432\u0434\u044b\u0432\u0430\u0435\u0442.<\/p>\n<p>  \u041d\u043e \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043a\u0442\u043e-\u0442\u043e \u0443\u0436\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u043b \u0440\u0435\u0441\u0443\u0440\u0441? \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043d\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0435 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0440\u0435\u0441\u0443\u0440\u0441 \u043d\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u0441\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0442\u043e\u043a \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443.<\/p>\n<p>  \u0410 \u0447\u0435\u0433\u043e \u0431\u044b \u043d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c? \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u043c \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043a\u0438 \u0431\u044b\u043b\u0438 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u044b \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u0430 \u043d\u0435 \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u00ab\u0411\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u043e\u00bb, \u2013 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0430 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0438 \u0441\u0430\u043c\u043e\u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0445\u043c\u044b\u043b\u044c\u043d\u0443\u043b\u0430\u0441\u044c.<\/p>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438. \u042f \u043f\u0440\u0438\u043c\u0435\u043d\u044e \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0439\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a:<\/p>\n<pre><code>struct Alone : mt::IScheduler {     Alone(mt::IService& service);      void schedule(Handler handler)     {         strand.post(std::move(handler));     }  private:     boost::asio::io_service::strand strand; }; <\/code><\/pre>\n<p>  \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Alone<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IService<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>io_service::strand<\/code> \u0438\u0437 <code>boost.asio<\/code>. \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a <code>boost.asio<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0432 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u042d\u0442\u043e \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441 (mutual exclusion).<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u0438\u0434\u0438\u043e\u043c\u0430 <code>Alone<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430, \u043c\u044b \u0431\u0435\u0437 \u0437\u0430\u0437\u0440\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u0435\u0441\u0442\u0438 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u043c\u043e\u0449\u044c \u043d\u0430\u0448\u0438\u0445 \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u0439 \u0438 \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0442\u0430\u043a \u0438 \u043d\u0430\u0434\u043e.<\/p>\n<p>  \u0414\u043b\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434:<\/p>\n<pre><code>struct MemCache {     boost::optional&lt;std::string&gt; get(const std::string& key);     void set(const std::string& key, const std::string& val); };  \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f ThreadPool common_pool(3);             \/\/ \u043e\u0431\u0449\u0438\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 Alone mem_alone(common_pool);          \/\/ \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e portal&lt;MemCache&gt;().Attach(mem_alone);  \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u0434\u043b\u044f \u043f\u0430\u043c\u044f\u0442\u0438  \/\/ \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 auto value = portal&lt;MemCache&gt;()-&gt;get(key); \/\/ \u0438\u043b\u0438 portal&lt;MemCache&gt;()-&gt;set(anotherKey, anotherValue); <\/code><\/pre>\n<p>  \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u0431\u0443\u0434\u0435\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0442\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0427\u0443\u0434\u0435\u0441\u0430, \u0434\u0430 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/cb8\/3bb\/64d\/cb83bb64d941456c92354358e4456101.jpeg\" width=\"640\" \/><\/div>\n<h4>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/h4>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0445\u043e\u0440\u043e\u0448\u043e \u0436\u0438\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0439 \u0441\u0440\u0435\u0434\u044b. \u041d\u043e \u0436\u0438\u0437\u043d\u044c \u043d\u0430 \u043d\u0430\u0448 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0438\u0434\u0435\u0430\u043b\u0438\u0437\u043c \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u0441\u0432\u044b\u0441\u043e\u043a\u0430, \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043f\u043b\u0435\u0432\u044b\u0432\u0430\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u043f\u043e\u0434\u0442\u0435\u0440\u0435\u0442\u044c\u0441\u044f \u0438 \u0438\u0434\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435, \u043d\u0435\u0432\u0437\u0438\u0440\u0430\u044f \u043d\u0430 \u0432\u0441\u0435 \u0442\u044f\u0433\u043e\u0442\u044b \u0438 \u043b\u0438\u0448\u0435\u043d\u0438\u044f.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/2cc\/26b\/701\/2cc26b7015ee4bddbfd1ff39cd376ad9.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0427\u0442\u043e \u0436\u0435 \u043d\u0430\u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438? \u0410 \u0442\u043e, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043a\u0430\u0436\u0443\u0449\u0438\u0435\u0441\u044f \u043d\u0435\u043f\u0440\u0435\u043b\u043e\u0436\u043d\u044b\u043c\u0438, \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u0432\u043d\u0435\u0441\u0442\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0432\u044b (\u0441\u043c. \u00ab\u043e\u0442\u043c\u0435\u043d\u0430\u00bb). \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u0448\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>  \u041d\u0443\u0436\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0444\u0430\u043a\u0442\u043e\u0440\u044b \u2013 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0445\u043e\u0440\u043e\u0448\u043e, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043d\u043e \u0435\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u043d\u0435 \u0432\u043e\u0432\u0440\u0435\u043c\u044f, \u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u043c. \u0420\u0430\u043d\u044c\u0448\u0435 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e! \u0427\u0442\u043e \u0442\u043e\u043b\u043a\u0443, \u0447\u0442\u043e \u043c\u044b \u0432\u044b\u0443\u0447\u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u0435\u0441\u043b\u0438 \u044d\u043a\u0437\u0430\u043c\u0435\u043d \u0431\u044b\u043b \u0432\u0447\u0435\u0440\u0430, \u0430 \u043c\u044b \u043d\u0430 \u043d\u0435\u0433\u043e \u043d\u0435 \u044f\u0432\u0438\u043b\u0438\u0441\u044c?<\/p>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u043e\u0436\u0430\u0442\u0441\u044f \u0442\u044f\u0436\u043a\u0438\u043c \u0431\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043d\u0430 \u044d\u0442\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0431\u0438\u0432\u0430\u044e\u0442 \u0438 \u043f\u043e\u0442\u043e\u043c \u0443\u0436\u0435 \u043e\u0433\u0440\u0435\u0431\u0430\u044e\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u043a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0432\u0438\u0441\u0438\u0442, \u0447\u0442\u043e-\u0442\u043e \u0442\u0443\u043f\u0438\u0442, \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0437\u0430\u043d\u044f\u0442\u044b, \u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0443\u043d\u044b\u043b\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u044d\u0442\u043e\u0439 \u0448\u0442\u0430\u043d\u0433\u0435.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0432\u0435\u0434\u0435\u043c \u0442\u0438\u043f\u044b \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439:<\/p>\n<pre><code>enum EventStatus {     ES_NORMAL,     ES_CANCELLED,     ES_TIMEDOUT, };  struct EventException : std::runtime_error {     EventException(EventStatus s);     EventStatus status();  private:     EventStatus st; }; <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u0438\u0437\u0432\u043d\u0435 (\u0441\u043c. \u043e\u0442\u043c\u0435\u043d\u0430) \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u043c \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u043c:<\/p>\n<pre><code>struct Goer {     Goer();     EventStatus reset();     bool cancel();     bool timedout();      private:     struct State     {         State() : status(ES_NORMAL) {}         EventStatus status;     };      bool setStatus0(EventStatus s);     State& state0();      std::shared_ptr&lt;State&gt; state; }; <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0432\u0441\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e: \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0443\u043c\u043d\u044b\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c.<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0432 \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441-\u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a <code>Journey<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:<\/p>\n<pre><code>void Journey::handleEvents() {     \/\/ \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u0438\u0437 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430     if (!eventsAllowed || std::uncaught_exception())         return;     auto s = gr.reset();     if (s == ES_NORMAL)         return; \/\/ \u043d\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0439     throw EventException(s); }  void Journey::disableEvents() {     handleEvents();     eventsAllowed = false; }  void Journey::enableEvents() {     eventsAllowed = true;     handleEvents(); } <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u043b\u0430\u0433\u0430, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043b\u0438 \u043d\u0435\u0442. \u0418\u043d\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u0430\u0436\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u0431\u0440\u043e\u0441\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u043a\u0440\u0443\u0442\u0438\u043c \u0441\u0442\u0435\u043a. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0437\u0430\u0449\u0438\u0442\u043d\u0438\u043a:<\/p>\n<pre><code>struct EventsGuard {     EventsGuard();  \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 disableEvents()     ~EventsGuard(); \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442  enableEvents() }; <\/code><\/pre>\n<p>  \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u0435\u0441\u043b\u043e\u0432\u0443\u0442\u044b\u0439 <code>handleEvents<\/code>? \u0410 \u0432\u043e\u0442 \u043a\u043e\u0433\u0434\u0430:<\/p>\n<pre><code>void Journey::defer(Handler handler) {     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u0445\u043e\u0434\u043e\u043c \u0438\u0437 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     handleEvents();     deferHandler = handler;     coro::yield();     \/\/ \u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f     handleEvents(); } <\/code><\/pre>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0442\u044f\u0436\u0435\u043b\u044b\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0442\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043d\u0430\u0448\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>handleEvents<\/code>. \u042d\u0442\u043e \u0440\u0435\u0448\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043e\u0442\u0437\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<pre><code>Goer go(Handler handler, mt::IScheduler& scheduler) {     return Journey::create(std::move(handler), scheduler); } <\/code><\/pre>\n<p>  <code>Journey::create<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>Goer<\/code> \u0434\u043b\u044f \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<pre><code>struct Journey {     \/\/ \u2026     Goer goer() const     {         return gr;     }     \/\/ \u2026  private:     \/\/ \u2026     Goer gr; };  Goer Journey::create(Handler handler, mt::IScheduler& s) {     return (new Journey(s))-&gt;start0(std::move(handler)); }  \/\/ \u0441\u043c. \u0437\u0430\u0434\u0430\u0447\u0443 1 Goer Journey::start0(Handler handler) {     \/\/ \u2026     return goer(); }  \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f: Goer op = go(myMegaHandler); \/\/ \u2026 If (weDontNeedMegaHandlerAnymore)     op.cancel(); <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 <code>op.cancel()<\/code> \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0438 \u043f\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0435 <code>handleEvents()<\/code> \u043e\u0442\u043c\u0435\u043d\u0430 \u043d\u0430\u0447\u043d\u0435\u0442 \u0441\u0432\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438 \u0440\u0430\u0441\u043a\u0440\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u043b\u043e.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/637\/9cc\/db9\/6379ccdb991042b1ab6ccac5b73202aa.jpeg\" width=\"640\" \/><\/div>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0443\u0441\u043f\u0435\u043b\u0438, \u043d\u0430\u0432\u0435\u0440\u043d\u043e, \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u0430 <code>Journey<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0442\u0443\u0434\u0430-\u0441\u044e\u0434\u0430, \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044f\u0441\u044c \u0441\u043a\u0432\u043e\u0437\u044c \u043f\u043e\u0440\u0442\u0430\u043b\u044b, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043a\u0440\u044b\u0442\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>go<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u0441\u043e \u0441\u043a\u0440\u044b\u0442\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \u041e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b: <code>go<\/code>, <code>defer<\/code>, <code>deferProceed<\/code> \u0438 \u0442. \u0434., \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u0430 <code>Journey<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f TLS.<\/p>\n<h4>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432<\/h4>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432:<\/p>\n<pre><code>struct Timeout {     Timeout(int ms);     ~Timeout();      private:     boost::asio::deadline_timer timer; }; <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>boost::asio::deadline_timer<\/code>:<\/p>\n<pre><code>Timeout::Timeout(int ms) :     timer(service&lt;TimeoutTag&gt;(), boost::posix_time::milliseconds(ms)) {     \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435     Goer goer = journey().goer();     \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a     timer.async_wait([goer](const Error& error) mutable {         \/\/ mutable, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 goer         if (!error) \/\/ \u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0442\u043c\u0435\u043d\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u0442\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0438\u043c             goer.timedout();     }); }  Timeout::~Timeout() {     \/\/ \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440     timer.cancel_one();     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0432\u0434\u0440\u0443\u0433 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435     handleEvents(); } <\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f RAII-\u0438\u0434\u0438\u043e\u043c\u0443, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u0434\u0440\u0443\u0433 \u0432 \u0434\u0440\u0443\u0433\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e, \u043d\u0438 \u0432 \u0447\u0435\u043c \u0441\u0435\u0431\u044f \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044f.<\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>\/\/ \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b Timeout t(100); \/\/ 100 \u043c\u0441 for (auto element: container) {     performOperation(element);     handleEvents(); } <\/code><\/pre>\n<p>  \u041d\u0435 \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0437\u0430 100 \u043c\u0441 \u2013 \u0434\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/bb8\/074\/9f8\/bb80749f87c64667afdf0379354d2ef9.jpeg\" \/><\/div>\n<p>  \u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432:<\/p>\n<pre><code>\/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 200 \u043c\u0441 \u043d\u0430 \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 Timeout outer(200); portal&lt;MyObject&gt;()-&gt;performOp(); {     \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 100 \u043c\u0441     \/\/ \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438     Timeout inner(100);     portal&lt;MyAnotherObject&gt;()-&gt;performAnotherOp();     \/\/ \u0430 \u044d\u0442\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u043c \u043e\u0442 \u043f\u043e\u0441\u044f\u0433\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432     EventsGuard guard;     performGuardedAction(); } <\/code><\/pre>\n<p>  <\/p>\n<h2>\u0417\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>  \u0417\u0430\u0434\u0430\u0447 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438 \u0443 \u043c\u0435\u043d\u044f \u0446\u0435\u043b\u044b\u0445 \u0434\u0432\u0435. \u0412\u043e\u043e\u0431\u0449\u0435, \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438 \u2013 \u043e\u0447\u0435\u043d\u044c \u00ab\u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f\u00bb \u0437\u0430\u0434\u0430\u0447\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043d\u0430\u0434 \u043d\u0438\u043c\u0438.<\/p>\n<p>  \u041a\u0430\u043a\u043e\u0432\u0430 \u0446\u0435\u043b\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f? \u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044e:  <\/p>\n<ol>\n<li>\u0410\u043d\u0430\u043b\u0438\u0437 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/li>\n<li>\u041a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u043c\u0435\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u044f. \u0417\u043d\u0430\u0442\u044c \u043e \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0445 \u043a\u0430\u043c\u043d\u044f\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0433\u043e \u043d\u0435 \u043e\u0433\u0440\u0435\u0441\u0442\u0438.<\/li>\n<li>\u041d\u0443 \u0438 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u2013 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u043c\u044f\u0442\u044c \u043c\u043e\u0437\u0433. \u0413\u043e\u0432\u043e\u0440\u044f\u0442, \u043e\u043d \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/li>\n<\/ol>\n<p>  <\/p>\n<h4>\u0417\u0430\u0434\u0430\u0447\u0430 1<\/h4>\n<p>  \u0418\u0442\u0430\u043a, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u0434 \u043d\u043e\u043c\u0435\u0440\u043e\u043c 1.<\/p>\n<p>  \u0418\u043c\u0435\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<pre><code>Goer Journey::start0(Handler handler) {     schedule0([handler, this] {         guardedCoro0()-&gt;start([handler] {             JLOG(&quot;started&quot;);             try             {                 handler();             }             catch (std::exception& e)             {                 (void) e;                 JLOG(&quot;exception in coro: &quot; &lt;&lt; e.what());             }             JLOG(&quot;ended&quot;);         });     });     return goer(); } <\/code><\/pre>\n<p>  \u0412\u043e\u0442 \u0440\u043e\u0432\u043d\u043e \u0432 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438. \u0413\u0434\u0435? \u0427\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a?<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041e\u0442\u0432\u0435\u0442<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>Goer Journey::start0(Handler handler)  { +    Goer gr = goer();      schedule0([handler, this] {          guardedCoro0()-&gt;start([handler] {              JLOG(&quot;started&quot;); @@ -121,7 +122,7 @@              JLOG(&quot;ended&quot;);          });      }); -    return goer(); +    return gr;  } <\/code><\/pre>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/f4d\/c0a\/9b2\/f4dc0a9b2dce4736a1b9f034304cb7eb.png\" \/><\/div>\n<p>  <\/div>\n<\/div>\n<h4>\u0417\u0430\u0434\u0430\u0447\u0430 2<\/h4>\n<p>  \u0422\u0430\u043a\u043e\u0435 \u0436\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435. \u0415\u0441\u0442\u044c \u043a\u043e\u0434:<\/p>\n<pre><code>void Journey::onExit0() {     if (deferHandler == nullptr)     {         delete this;     }     else     {         deferHandler();         deferHandler = nullptr;     }     t_journey = nullptr; } <\/code><\/pre>\n<p>  \u0413\u0434\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u043a\u0430\u043a \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c?<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041e\u0442\u0432\u0435\u0442<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>     { @@ -153,8 +154,8 @@ -        deferHandler(); -        deferHandler = nullptr; +        Handler handler = std::move(deferHandler); +        handler();      } <\/code><\/pre>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/74e\/9b1\/965\/74e9b196567a4f89897bd0e2290cbed4.png\" width=\"640\" \/><\/div>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0437\u0430\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c defer handler, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u0432\u043e\u0439\u043d\u043e\u0435 \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430.  <\/div>\n<\/div>\n<h2>\u0411\u043e\u043d\u0443\u0441: \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 (GC)<\/h2>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/d52\/201\/a0c\/d52201a0cc7f4417824a3c3805b2fc28.jpeg\" width=\"640\" \/><\/div>\n<p>  \u0414\u0430, \u0434\u0430, \u0437\u0430\u0431\u0443\u0431\u0435\u043d\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 GC \u043d\u0430 \u043d\u0430\u0448\u0438\u0445 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445. \u041d\u0430\u0447\u043d\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430:<\/p>\n<pre><code>struct A   { ~A() { TLOG(&quot;~A&quot;); } }; struct B:A { ~B() { TLOG(&quot;~B&quot;); } }; struct C   { ~C() { TLOG(&quot;~C&quot;); } };  ThreadPool tp(1, &quot;tp&quot;); go([] {     A* a = gcnew&lt;B&gt;();     C* c = gcnew&lt;C&gt;(); }, tp); <\/code><\/pre>\n<p>  \u0412\u044b\u0432\u043e\u0434 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438:  <\/p>\n<pre><code>tp#1: ~C tp#1: ~B tp#1: ~A <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432! \u0425\u043e\u0442\u044f \u043a\u043e\u0435-\u043a\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b.<\/p>\n<p>  \u0412\u0441\u044f \u043c\u0430\u0433\u0438\u044f, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0441\u043f\u0440\u044f\u0442\u0430\u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0438:<\/p>\n<pre><code>template&lt;typename T, typename... V&gt; T* gcnew(V&&... v) {     return gc().add(new T(std::forward(v)...)); }  GC& gc() { return journey().gc; }  struct GC {     ~GC()     {         \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435         for (auto& deleter: boost::adaptors::reverse(deleters))             deleter();     }      template&lt;typename T&gt; T* add(T* t)     {         \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u0434\u0430\u043b\u044f\u0442\u043e\u0440 \u0442\u0438\u043f\u0430 T         deleters.emplace_back([t] { delete t; });         return t;     }  private:     std::vector&lt;Handler&gt; deleters; }; <\/code><\/pre>\n<p>  \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>GC<\/code> \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u0430 <code>Journey<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0440\u0443\u0448\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u043d\u0430\u0448\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435: \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u043c\u0438, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u043b\u0438\u0448\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<h2>\u0412\u044b\u0432\u043e\u0434\u044b<\/h2>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439:  <\/p>\n<ol>\n<li>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439\/\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/li>\n<li>\u041f\u0443\u043b\u044b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438.<\/li>\n<li>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f.<\/li>\n<li>\u0422\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u043c\u0438.<\/li>\n<li>\u041f\u043e\u0440\u0442\u0430\u043b\u044b \u2013 \u043c\u043e\u0449\u043d\u0430\u044f \u0438 \u0433\u0438\u0431\u043a\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435: \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0433\u0440\u0443\u043f\u043f\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0438 \u0442. \u0434.<\/li>\n<\/ol>\n<p>  \u041f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0439 \u043a\u043e\u0434, \u043d\u0435 \u0440\u0430\u0441\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u044f\u0441\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u041e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442 \u043f\u043e\u0442\u043e\u043a\u0438, \u0447\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u0432 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438. \u0410 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u043e\u0432 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 \u043d\u043e\u0432\u044b\u0439, \u0434\u043e\u0441\u0435\u043b\u0435 \u043d\u0435\u0432\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c.<\/p>\n<p>  \u041f\u043e\u0440\u0442\u0430\u043b\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u0438\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443. \u042d\u0442\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432 \u0433\u0435\u0442\u0435\u0440\u043e\u0433\u0435\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445: \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0435\u0442\u044c, \u0434\u0438\u0441\u043a, UI, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0442\u044f\u0436\u0435\u043b\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0445 \u0442\u0435\u0445 \u0437\u0430\u0434\u0430\u0447, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f\u043c\u0438 \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c\u0438.<\/p>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445. \u0421\u0430\u043c\u0430\u044f \u043c\u044f\u043a\u043e\u0442\u043a\u0430 \u0435\u0449\u0435 \u0432\u043f\u0435\u0440\u0435\u0434\u0438! \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0441\u0442\u0430\u0442\u044c\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0430 \u0432\u0430\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/535\/5ac\/710\/5355ac710de64bd6a9d4dc2e7d1e71c6.jpeg\" width=\"640\" \/><\/div>\n<p>  \u041a\u043e\u0434<br \/>  <a href=\"https:\/\/bitbucket.org\/gridem\/synca\">bitbucket.org\/gridem\/synca<\/a><\/p>\n<p>  \u041f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f C++ Party, Yandex<br \/>  <a href=\"https:\/\/tech.yandex.ru\/events\/cpp-party\/march-msk\/talks\/1761\/\">tech.yandex.ru\/events\/cpp-party\/march-msk\/talks\/1761\/<\/a><\/p>\n<p>  \u041f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f C++ User Group<br \/>  <a href=\"http:\/\/youtu.be\/uUQX5QS1CCg\">youtu.be\/uUQX5QS1CCg<\/a><br \/>  <a href=\"http:\/\/habrahabr.ru\/post\/212793\/\">habrahabr.ru\/post\/212793\/<\/a><\/p>\n<p>  \u041b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0430<br \/>  [1] \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c: \u043d\u0430\u0437\u0430\u0434 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/201826\/\">habrahabr.ru\/post\/201826\/<\/a><br \/>  [2] \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Akka-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 <a href=\"http:\/\/doc.akka.io\/docs\/akka\/2.1.4\/scala\/scheduler.html\">doc.akka.io\/docs\/akka\/2.1.4\/scala\/scheduler.html<\/a>      \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/company\/yandex\/blog\/240525\/\"> http:\/\/habrahabr.ru\/company\/yandex\/blog\/240525\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">     \t<a href=\"http:\/\/habrahabr.ru\/company\/yandex\/blog\/240525\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/f0a\/1c5\/0ac\/f0a1c50ac50944079d72728394c600f7.jpeg\" width=\"640\" \/><\/div>\n<p><\/a><\/p>\n<p>  \u041d\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0438 \u0433\u043e\u0434\u0430, \u043a\u0430\u043a \u044f \u0434\u043e\u0431\u0440\u0430\u043b\u0441\u044f \u0434\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442 \u0438\u0434\u0435\u0438 \u0442\u043e\u0439, \u0441\u0430\u043c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c <a href=\"http:\/\/habrahabr.ru\/post\/201826\/\">[1]<\/a>. \u0412 \u043d\u0435\u0439 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0430 \u043c\u043e\u0449\u044c \u0438 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438 (race-condition), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0431\u043e\u043d\u0443\u0441.  <\/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-240525","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/240525","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=240525"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/240525\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=240525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=240525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=240525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}