{"id":276678,"date":"2016-03-22T11:08:02","date_gmt":"2016-03-22T08:08:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=276678"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=276678","title":{"rendered":"\u041f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f"},"content":{"rendered":"<p>       \u0412 \u043c\u0438\u0440\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u0432 C++. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0443 \u0432\u0441\u0435\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u044f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f, \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u0417\u0434\u0435\u0441\u044c \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e\u0431 \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445, \u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u044b?<\/h2>\n<p>  \u0414\u0443\u043c\u0430\u044e, \u043c\u043d\u043e\u0433\u0438\u0435 \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0435\u0439, \u043d\u043e \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432\u0441\u0451 \u0436\u0435 \u043d\u0430\u043f\u0438\u0448\u0443.<\/p>\n<p>  \u0421\u0438\u0433\u043d\u0430\u043b \u2014 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430. \u0415\u0441\u043b\u0438 \u0443\u0433\u043e\u0434\u043d\u043e, callback \u0441 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439. \u0418\u043b\u0438, \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 .NET, multicast delegate.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0430\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441 boost::signals2<\/b><\/p>\n<div class=\"spoiler_text\">\u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"cpp\">struct Button {     boost::signals2::signal&lt;void()&gt; OnClick; }; <\/code><\/pre>\n<p>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 \u043d\u0435\u0433\u043e:<\/p>\n<pre><code class=\"cpp\">void ClickHandler() { cout &lt;&lt; \u201cButton clicked\u201d &lt;&lt; endl; }  \/\/ ...  boost::signals2::connection c = button-&gt;OnClick.connect(&ClickHandler);  \/\/ ...  c.disconnect(); <\/code><\/pre>\n<p>  \u0412\u044b\u0437\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"cpp\">struct Button {     boost::signals2::signal&lt;void()&gt; OnClick;  private:     void MouseDownHandler()     {         OnClick();     } }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h2>\u0422\u0435\u043f\u0435\u0440\u044c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445<\/h2>\n<p>  \u0412 \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u043d\u043e \u0447\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0433\u043e?<\/p>\n<p>  \u0422\u0443\u0442, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u043e\u0431\u0449\u0438\u0445 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<ol>\n<li>\u041d\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/li>\n<li>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430<\/li>\n<li>\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430<\/li>\n<\/ol>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u0436\u0434\u0443\u044e \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0448\u0438\u0432\u043a\u0438 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0439 \u043c\u0435\u0434\u0438\u0430-\u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<ul>\n<li><b>StorageManager<\/b> \u2014 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0444\u043b\u044d\u0448\u043a\u0438, DVD-\u0434\u0438\u0441\u043a\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0442\u0430\u0432\u0438\u043b \u0432 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0443<\/li>\n<li><b>MediaScanner<\/b> \u2014 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u043c\u0435\u0434\u0438\u0430-\u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432<\/li>\n<li><b>MediaUiModel<\/b> \u2014 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043c\u0435\u0434\u0438\u0430-\u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u043c Model-View-\u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435<\/li>\n<\/ul>\n<p>  \u0421\u0440\u0430\u0437\u0443 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0442\u0443\u0442 \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0451\u043d, \u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0441\u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445. \u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0435 \u0442\u0438\u043f\u044b \u0432\u0438\u0434\u0430 <i>TypePtr<\/i>. \u042d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c <i>std::shared_ptr&lt;Type&gt;<\/i>, \u043d\u0435 \u043f\u0443\u0433\u0430\u0439\u0442\u0435\u0441\u044c.<\/p>\n<h2>\u041d\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/h2>\n<p>  \u0418\u0442\u0430\u043a, <i>StorageManager<\/i>. \u041d\u0443\u0436\u0435\u043d \u0433\u0435\u0442\u0442\u0435\u0440 \u0434\u043b\u044f \u0442\u0435\u0445 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0443, \u0438 \u0441\u0438\u0433\u043d\u0430\u043b \u0434\u043b\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445.<\/p>\n<pre><code class=\"cpp\">class StorageManager { public:     std::vector&lt;StoragePtr&gt; GetStorages() const;     boost::signals2::signal&lt;void(const StoragePtr&)&gt; OnStorageAdded;      \/\/ ... }; <\/code><\/pre>\n<p>  \u0423\u0432\u044b, \u0442\u0430\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c race condition.<\/p>\n<p>  \u041d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435\u2026<\/p>\n<pre><code class=\"cpp\">storageManager-&gt;OnStorageAdded.connect(&StorageHandler);  \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u043b\u044d\u0448\u043a\u0443 \u0434\u043e \u0446\u0438\u043a\u043b\u0430, \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0434\u0432\u0430\u0436\u0434\u044b for (auto&& storage : storageManager-&gt;GetStorages())     StorageHandler(storage); <\/code><\/pre>\n<p>  \u2026 \u0438 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/p>\n<pre><code class=\"cpp\">for (auto&& storage : storageManager-&gt;GetStorages())     StorageHandler(storage);  \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u043b\u044d\u0448\u043a\u0443 \u0434\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443, \u043e\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0441\u043e\u0432\u0441\u0435\u043c storageManager-&gt;OnStorageAdded.connect(&StorageHandler); <\/code><\/pre>\n<p>  <\/p>\n<h3>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/h3>\n<p>  \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0440\u0430\u0437 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 race condition, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043c\u044c\u044e\u0442\u0435\u043a\u0441.<\/p>\n<pre><code class=\"cpp\">class StorageManager {     mutable std::recursive_mutex   _mutex;     std::vector&lt;StoragePtr&gt;        _storages;  public:     StorageManager()     { \/* ... *\/ }      boost::signals2::signal&lt;void(const StoragePtr&)&gt; OnStorageAdded;      std::recursive_mutex& GetMutex() const     { return _mutex; }      std::vector&lt;StoragePtr&gt; GetStorages() const     {         std::lock_guard&lt;std::recursive_mutex&gt; l(_mutex);         return _storages;     }  private:     void ReportNewStorage(const StoragePtr& storage)     {         std::lock_guard&lt;std::recursive_mutex&gt; l(_mutex);          _storages.push_back(storage);         OnStorageAdded(storage);     } };  \/\/ ...  {     std::lock_guard&lt;std::recursive_mutex&gt; l(storageManager-&gt;GetMutex());      storageManager-&gt;OnStorageAdded.connect(&StorageHandler);     for (auto&& storage : storageManager-&gt;GetStorages())         StorageHandler(storage); } <\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u043e \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432:<\/p>\n<ul>\n<li>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <i>std::mutex<\/i> \u0432\u043c\u0435\u0441\u0442\u043e <i>std::recursive_mutex<\/i>, \u0432\u044b \u0442\u0435\u0440\u044f\u0435\u0442\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <i>GetStorages<\/i>, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <i>StorageManager<\/i> \u043d\u0435\u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c<\/li>\n<li>\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 <i>GetStorages<\/i>, \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c <i>StorageManager<\/i>&#8216;\u0430<\/li>\n<li>\u0412\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0440\u0443\u0436\u0443 \u0442\u0438\u043f <i>std::vector&lt;StoragePtr&gt;<\/i>, \u0445\u043e\u0442\u044f \u043d\u0430 \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/li>\n<li>\u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u0451\u043c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435?<\/h3>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0451\u043c \u0432\u0441\u0451 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0432\u043e\u043a\u0440\u0443\u0433 \u0432\u044b\u0437\u043e\u0432\u0430 <i>connect<\/i> (\u0437\u0430\u0445\u0432\u0430\u0442 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430 \u0438 \u043e\u0431\u0445\u043e\u0434 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438) \u0432\u043d\u0443\u0442\u0440\u044c.<\/p>\n<p>  \u0422\u0443\u0442 \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043f\u0440\u0438\u0440\u043e\u0434\u044b \u044d\u0442\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0436\u0435 \u044d\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, enum, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043d\u0435\u043a\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f.<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u0438\u0433\u043d\u0430\u043b <b>\u043f\u043e\u043f\u0443\u043b\u044f\u0442\u043e\u0440<\/b> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f, \u0438 \u043f\u0443\u0441\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 (StorageManager, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435) \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u044d\u0442\u043e\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a.<\/p>\n<pre><code class=\"cpp\">template &lt; typename Signature &gt; class signal {     using populator_type = std::function&lt;void(const std::function&lt;Signature&gt;&)&gt;;      mutable std::mutex                       _mutex;     std::list&lt;std::function&lt;Signature&gt; &gt;     _handlers;     populator_type                           _populator;  public:     signal(populator_type populator)         : _populator(std::move(populator))     { }      std::mutex& get_mutex() const { return _mutex; }      signal_connection connect(std::function&lt;Signature&gt; handler)     {         std::lock_guard&lt;std::mutex&gt; l(_mutex);          _populator(handler); \/\/ \u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f         _handlers.push_back(std::move(handler)); \t         return signal_connection([&]() { \/* \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 _handlers *\/ } );     }      \/\/ ... }; <\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441 <i>signal_connection<\/i> \u043f\u043e\u043a\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044f\u043c\u0431\u0434\u0430-\u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0434\u0430\u043b\u0438\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0435. \u0427\u0443\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  \u041f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c <i>StorageManager<\/i> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0439 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438:<\/p>\n<pre><code class=\"cpp\">class StorageManager {     std::vector&lt;StoragePtr&gt;        _storages;  public:     StorageManager()         : _storages([&](const std::function&lt;void(const StoragePtr&)&gt;& h) { for (auto&& s : _storages) h(s); })     { \/* ... *\/ }      signal&lt;void(const StoragePtr&)&gt; OnStorageAdded;  private:     void ReportNewStorage(const StoragePtr& storage)     {         \/\/ \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0443\u0442, \u0430 \u043d\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0430,         \/\/ \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e _storages         std::lock_guard&lt;std::mutex&gt; l(OnStorageAdded.get_mutex());          _storages.push_back(storage);         OnStorageAdded(storage);     } }; <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 C++14, \u043f\u043e\u043f\u0443\u043b\u044f\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c:<\/p>\n<pre><code class=\"cpp\">StorageManager()     : _storages([&](auto&& h) { for (auto&& s : _storages) h(s); }) { } <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <i>signal::connect<\/i>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0442\u0435\u043b\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>  \u041a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c:<\/p>\n<pre><code class=\"cpp\">storageManager-&gt;OnStorageAdded.connect(&StorageHandler); <\/code><\/pre>\n<p>  \u041e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043c\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041e\u0442\u043b\u0438\u0447\u043d\u043e!<\/p>\n<h2>\u041d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430<\/h2>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0440\u0430 \u043f\u0438\u0441\u0430\u0442\u044c <i>MediaScanner<\/i>. \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c\u0441\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443 <i>StorageManager::OnStorageAdded<\/i>, \u0430 \u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043c\u0441\u044f.<\/p>\n<pre><code class=\"cpp\">class MediaScanner { private:     boost::signals2::connection _connection;  public:     MediaScanner(const StorageManagerPtr& storageManager)     { _connection = storageManager-&gt;OnStorageAdded.connect([&](const StoragePtr& s) { this-&gt;StorageHandler(s); }); }      ~MediaScanner()     {         _connection.disconnect();         \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u0432\u044b\u0437\u0432\u0430\u0432\u0448\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b.         \/\/ \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0434\u0430\u043b\u0435\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 MediaScanner.     }  private:     void StorageHandler(const StoragePtr& storage)     { \/* \u0417\u0434\u0435\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u043e\u043b\u0433\u043e\u0435 *\/ } }; <\/code><\/pre>\n<p>  \u0423\u0432\u044b, \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0434\u0430\u0442\u044c. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <i>disconnect<\/i> \u0432\u043e \u0432\u0441\u0435\u0445 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u043c\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u0445. \u041e\u043d \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0441\u0438\u0433\u043d\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0435\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0442\u043e \u043e\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0440\u0432\u0430\u043d, \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c <i>MediaScanner<\/i>.<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 Qt<\/h3>\n<p>  \u0412 Qt \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443, \u0438 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u0414\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430 <i>disconnect<\/i>\/<i>deleteLater<\/i>.<\/p>\n<pre><code class=\"cpp\">mediaScanner-&gt;disconnect(); mediaScanner-&gt;deleteLater(); <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 <i>MediaScanner<\/i> \u043e\u0442 \u0432\u0441\u0435\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d \u0431\u044b\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d, \u0430 \u043f\u043e\u0441\u043b\u0435 \u043a\u043b\u0430\u0434\u0451\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 <b>\u043f\u043e\u0441\u043b\u0435<\/b> \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043c \u0443\u0436\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b\u0442\u044c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 <i>MediaScanner<\/i> \u043d\u0438 \u043e\u0434\u0438\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0443\u0436\u0435 \u0442\u043e\u0447\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c\u0441\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443.<\/p>\n<p>  \u042d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0451 \u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<ul>\n<li>\u041e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0441\u0430\u043c, \u0447\u0442\u043e \u043b\u0438\u0447\u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435\u043c \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u0438<\/li>\n<li>\u0418\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u0432\u0430\u043c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0441\u0442\u0440\u043e\u0433\u0430\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 <i>MediaScanner<\/i>&#8216;\u043e\u043c \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043d\u043e \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d. \u0415\u0441\u043b\u0438 \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 <i>MediaScanner<\/i>&#8216;a \u0443\u0434\u0430\u043b\u0438\u0442 \u0435\u0433\u043e, \u043f\u043e\u043a\u0430 \u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0435\u0449\u0451 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0441\u0441\u044b\u043b\u043a\u0438, \u0432\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u043f\u0430\u0434\u0451\u0442<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 boost::signals2<\/h3>\n<p>  \u0411\u0443\u0441\u0442 \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b <i>track<\/i>\/<i>track_foreign<\/i> \u0432 \u0441\u043b\u043e\u0442\u0435 (\u0442. \u0435. \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435). \u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 <i>weak_ptr<\/i> \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043f\u043e\u043a\u0430 \u0436\u0438\u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u00ab\u0441\u043b\u0435\u0434\u0438\u0442\u00bb \u0441\u043b\u043e\u0442.<\/p>\n<p>  \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e: \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u043b\u043e\u0442\u0435 \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f <i>weak_ptr<\/i>&#8216;\u043e\u0432 \u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u00ab\u043b\u043e\u0447\u0430\u0442\u0441\u044f\u00bb (\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u0435) \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u044d\u0442\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043d\u0435 \u0440\u0430\u0437\u0440\u0443\u0448\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u043a\u0430 \u043a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u043a \u043d\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0443\u0436\u0435 \u0431\u044b\u043b \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c <i>weak_ptr<\/i> \u043d\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0441\u0430\u043c\u044b\u0439 \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0430\u0431\u0440\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <i>MediaScanner<\/i>, \u0433\u0434\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u0432\u0441\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0435\u043c\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u044b:<\/p>\n<pre><code class=\"cpp\">class MediaScanner { public:     static std::shared_ptr&lt;MediaScanner&gt; Create(const StorageManagerPtr& storageManager)     {         std::lock_guard&lt;std::recursive_mutex&gt; l(storageManager-&gt;GetMutex());          MediaScannerPtr result(new MediaScanner);          boost::signals2::signal&lt;void(const StoragePtr&)&gt;::slot_type             slot(bind(&MediaScanner::StorageHandler, result.get(), _1));         slot.track_foreign(result);          storageManager-&gt;OnStorageAdded.connect(slot);         for (auto&& storage : storageManager-&gt;GetStorages())             result-&gt;StorageHandler(storage);          return result;     }  private:     MediaScanner() \/\/ \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440!     { \/* \u041f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0451, \u043a\u0440\u043e\u043c\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 *\/ }      void StorageHandler(const StoragePtr& storage);     { \/* \u0417\u0434\u0435\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u043e\u043b\u0433\u043e\u0435 *\/ } }; <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\u041e-\u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0431\u0443\u0434\u0435\u0442\u0435 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c<\/li>\n<li>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <i>MediaScanner<\/i>&#8216;\u0430 \u0440\u0430\u0441\u043f\u0430\u043b\u0430\u0441\u044c \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438: \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <i>Create<\/i>, \u0438 \u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435<\/li>\n<li>\u0412\u044b <b>\u043e\u0431\u044f\u0437\u0430\u043d\u044b<\/b> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <i>shared_ptr<\/i> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f <i>MediaScanner<\/i><\/li>\n<li>\u0412\u044b \u043d\u0435 \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e <i>MediaScanner<\/i> \u0443\u0434\u0430\u043b\u0451\u043d, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0435\u0433\u043e. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u0435\u0441\u043b\u0438 \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f <i>MediaScanner<\/i><\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435?<\/h3>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <i>disconnect<\/i> \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d \u0432\u0435\u0440\u043d\u0451\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c \u0432\u0441\u0451, \u043a \u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043b \u0434\u043e\u0441\u0442\u0443\u043f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0430. \u0427\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <i>std::thread::join<\/i>.<\/p>\n<p>  \u0417\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0451\u0434, \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u043d\u0430\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<ul>\n<li><b>life_token<\/b> \u2014 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0435\u0433\u043e, \u043a\u0430\u043a \u00ab\u0443\u043c\u0438\u0440\u0430\u044e\u0449\u0438\u0439\u00bb, \u0438 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e<\/li>\n<li><b>life_token::checker<\/b> \u2014 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0440\u044f\u0434\u043e\u043c \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c, \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0432\u043e\u0439 <i>life_token<\/i><\/li>\n<li><b>life_token::checker::execution_guard<\/b> \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <i>life_token<\/i> \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043d\u0435 \u00ab\u0443\u043c\u0435\u0440\u00bb \u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0440\u0430\u043d\u0435\u0435<\/li>\n<\/ul>\n<p>  \u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <i>signal_connection<\/i>:<\/p>\n<pre><code class=\"cpp\">class signal_connection {     life_token               _token;     std::function&lt;void()&gt;    _eraseHandlerFunc;  public:     signal_connection(life_token token, std::function&lt;void()&gt; eraseHandlerFunc)         : _token(token), _eraseHandlerFunc(eraseHandlerFunc)     { }      ~signal_connection();     { disconnect(); }      void disconnect()     {         if (_token.released())             return;          _token.release(); \/\/ \u0422\u0443\u0442 \u043c\u044b \u0436\u0434\u0451\u043c, \u0435\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d (\u0442. \u0435. \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f)         _eraseHandler(); \/\/ \u0422\u0430 \u0441\u0430\u043c\u0430\u044f \u043b\u044f\u043c\u0431\u0434\u0430-\u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0434\u0430\u043b\u0438\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430     } }; <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a RAII-\u0448\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. \u041e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0443, \u0441\u043a\u0430\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u041a\u043b\u0430\u0441\u0441 <i>signal<\/i> \u0443 \u043d\u0430\u0441 \u0442\u043e\u0436\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"cpp\">template &lt; typename Signature &gt; class signal {     using populator_type = std::function&lt;void(const std::function&lt;Signature&gt;&)&gt;;      struct handler     {         std::function&lt;Signature&gt;    handler_func;         life_token::checker         life_checker;     };      mutable std::mutex            _mutex;     std::list&lt;handler&gt;            _handlers;     populator_type                _populator;  public:     \/\/ ...      signal_connection connect(std::function&lt;Signature&gt; handler)     {         std::lock_guard&lt;std::mutex&gt; l(_mutex);          life_token token;         _populator(handler);         _handlers.push_back(Handler{std::move(handler), life_token::checker(token)}); \t         return signal_connection(token, [&]() { \/* \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 _handlers *\/ } );     }      template &lt; typename... Args &gt;     void operator() (Args&&... args) const     {         for (auto&& handler : _handlers)         {             life_token::checker::execution_guard g(handler.life_checker);             if (g.is_alive())                 handler.handler_func(forward&lt;Args&gt;(args)...);         }     } }; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0440\u044f\u0434\u043e\u043c \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u043b\u0435\u0436\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <i>life_token::checker<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <i>life_token<\/i>, \u043b\u0435\u0436\u0430\u0449\u0438\u0439 \u0432 <i>signal_connection<\/i>. \u0415\u0433\u043e \u043c\u044b \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <i>life_token::checker::execution_guard<\/i><\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u043f\u0440\u044f\u0447\u0443 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440. \u0415\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043b\u0438, \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c.<\/b><\/p>\n<div class=\"spoiler_text\">\u0412\u043d\u0443\u0442\u0440\u0438 <i>life_token<\/i> \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<ul>\n<li>\u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432 <i>life_token::release<\/i> (\u0437\u0434\u0435\u0441\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u043c\u044c\u044e\u0442\u0435\u043a\u0441)<\/li>\n<li>\u0424\u043b\u0430\u0433 \u00ab\u0436\u0438\u0432\/\u043c\u0451\u0440\u0442\u0432\u00bb<\/li>\n<li>\u0421\u0447\u0451\u0442\u0447\u0438\u043a \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <i>execution_guard<\/i> (\u0437\u0434\u0435\u0441\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043e\u043f\u0443\u0441\u0442\u0438\u043c)<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"cpp\">class life_token {     struct impl     {         std::mutex              mutex;         bool                    alive = true;     };      std::shared_ptr&lt;impl&gt;       _impl;  public:     life_token() : _impl(std::make_shared&lt;impl&gt;()) { }     ~life_token() { release(); }     bool released() const { return !_impl; }      void release()     {         if (released())             return;          std::lock_guard&lt;std::mutex&gt; l(_impl-&gt;mutex);         _impl-&gt;alive = false;         _impl.reset();     }      class checker     {         shared_ptr&lt;impl&gt;\t_impl;      public:         checker(const life_token& t) : _impl(t._impl) { }          class execution_guard         {             shared_ptr&lt;Impl&gt;\t_impl;          public:             execution_guard(const checker& c) : _impl(c._impl) { _impl-&gt;mutex.lock(); }             ~execution_guard() { _impl-&gt;mutex.unlock(); }             bool is_alive() const { return _impl-&gt;alive; }         };     }; }; <\/code><\/pre>\n<p>  \u041c\u044c\u044e\u0442\u0435\u043a\u0441 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 <i>execution_guard<\/i>. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0432 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434 <i>life_token::release<\/i>, \u043e\u043d \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0445\u0432\u0430\u0442\u0435 \u0442\u043e\u0433\u043e \u0436\u0435 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430 \u0438 \u0434\u043e\u0436\u0434\u0451\u0442\u0441\u044f \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0441\u0431\u0440\u043e\u0441\u0438\u0442 \u0444\u043b\u0430\u0433 <i>alive<\/i>, \u0438 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443\u0442 \u043a \u0432\u044b\u0437\u043e\u0432\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430.  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u043e\u0434 <i>MediaScanner<\/i>? \u0420\u043e\u0432\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430\u043c \u0438 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0435\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435:<\/p>\n<pre><code class=\"cpp\">class MediaScanner { private:     signals_connection    _connection;  public:     MediaScanner(const StorageManagerPtr& storageManager)     { _connection = storageManager-&gt;OnStorageAdded.connect([&](const StoragePtr& s) { this-&gt;StorageHandler(s); }); }      ~MediaScanner()     { _connection.disconnect(); }  private:     void StorageHandler(const StoragePtr& storage)     { \/* \u0417\u0434\u0435\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u043e\u043b\u0433\u043e\u0435 *\/ } }; <\/code><\/pre>\n<p>  <\/p>\n<h2>\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430<\/h2>\n<p>  \u041f\u0438\u0448\u0435\u043c <i>MediaUiModel<\/i>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0434\u0438\u0430-\u0444\u0430\u0439\u043b\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0441\u0435\u0431\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u044f \u0438\u0445 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 <i>MediaScanner<\/i> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u0433\u043d\u0430\u043b:<\/p>\n<pre><code class=\"cpp\">signal&lt;void(const MediaPtr&)&gt; OnMediaFound; <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<ul>\n<li>\u041c\u043e\u0434\u0435\u043b\u044c \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 UI-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 UI.<\/li>\n<li>\u0427\u0430\u0441\u0442\u043e \u0432 UI-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <i>shared_ptr<\/i> \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0444\u043e\u043a\u0443\u0441 \u0441 <i>track<\/i>\/<i>track_foreign<\/i> \u0442\u0443\u0442 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0451\u0442, \u043d\u043e \u044d\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0442\u0432\u043e\u0440\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"cpp\">class MediaUiModel : public UiModel&lt;MediaUiModelRow&gt; { private:     boost::io_service&             _uiThread;     boost::signals2::connection    _connection;  public:     MediaUiModel(boost::io_service& uiThread, const MediaScanner& scanner)         : _uiThread(uiThread)     {         std::lock_guard&lt;std::recursive_mutex&gt; l(scanner.GetMutex());         scanner.OnMediaFound.connect([&](const MediaPtr& m) { this-&gt;MediaHandler(m); });         for (auto&& m : scanner.GetMedia())             AppendRow(MediaUiModelRow(m))     }      ~MediaUiModel()     { _connection.disconnect(); }  private:     \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435 MediaScanner'\u0430, \u0438 \u0432\u0441\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u043f\u043e\u0442\u043e\u043a UI.     void MediaHandler(const MediaPtr& m)     { _uiThread.post([&]() { this-&gt;AppendRow(MediaUiModelRow(m)); }); } }; <\/code><\/pre>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430. \u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u043b, \u043c\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u043f\u043e\u0442\u043e\u043a UI. \u0415\u0441\u043b\u0438 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u00ab\u0413\u0430\u043b\u0435\u0440\u0435\u044f\u00bb), \u0432\u0441\u0435 \u044d\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0437\u0436\u0435 \u0432 \u043c\u0451\u0440\u0442\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u0418 \u043e\u043f\u044f\u0442\u044c \u043f\u0430\u0434\u0435\u043d\u0438\u0435.<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 Qt<\/h3>\n<p>  \u0412\u0441\u0451 \u0442\u0435 \u0436\u0435 <i>disconnect<\/i>\/<i>deleteLater<\/i>, \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u0430\u043c\u0438 \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0430\u043c\u0438.<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 boost::signals2<\/h3>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043f\u043e\u0432\u0435\u0437\u043b\u043e, \u0438 \u0432\u0430\u0448 UI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 <i>deleteLater<\/i>, \u0432\u044b \u0441\u043f\u0430\u0441\u0435\u043d\u044b. \u0412\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <i>disconnect<\/i>, \u0438 \u0436\u0438\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 Qt. \u041f\u0440\u0430\u0432\u0434\u0430, \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432\u0430\u043c \u0432\u0441\u0451 \u0436\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0441\u0434\u0435\u043b\u0430\u0435\u0442\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 <i>shared_ptr<\/i> \u043d\u0430 \u043d\u0435\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u044b. \u041a\u043e\u0434\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e, \u043d\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u0442\u0435\u0445\u043d\u0438\u043a\u0438.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u0430\u043c \u043d\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e, \u0438 \u0432\u0430\u0448 UI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0435\u043c\u0443 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <i>life_token<\/i>.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a (\u0442\u043e\u0436\u0435 \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0447\u0438\u0442\u0430\u0439\u0442\u0435, \u0435\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043b\u0438).<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">template &lt; typename Signature_ &gt; class AsyncToUiHandlerWrapper { private:     boost::io_service&          _uiThread;     std::function&lt;Signature_&gt;   _realHandler;     bool                        _released;     mutable std::mutex          _mutex;  public:     AsyncToUiHandlerWrapper(boost::io_service& uiThread, std::function&lt;Signature_&gt; realHandler)         : _uiThread(uiThread), _realHandler(realHandler), _released(false)     { }      void Release()     {         std::lock_guard&lt;std::mutex&gt; l(_mutex);         _released = true;     }      template &lt; typename... Args_ &gt;     static void AsyncHandler(const std::weak_ptr&lt;AsyncToUiHandlerWrapper&gt;& selfWeak, Args_&&... args)     {         auto self = selfWeak.lock();          std::lock_guard&lt;std::mutex&gt; l(self-&gt;_mutex);         if (!self-&gt;_released) \/\/ AsyncToUiHandlerWrapper \u043d\u0435 \u0431\u044b\u043b \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0451\u043d, \u0437\u043d\u0430\u0447\u0438\u0442 _uiThread \u0432\u0441\u0451 \u0435\u0449\u0451 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0436\u0438\u0432\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442             self-&gt;_uiThread.post(std::bind(&AsyncToUiHandlerWrapper::UiThreadHandler&lt;Args_&...&gt;, selfWeak, std::forward&lt;Args_&gt;(args)...)));     }  private:     template &lt; typename... Args_ &gt;     static void UiThreadHandler(const std::weak_ptr&lt;AsyncToUiHandlerWrapper&gt;& selfWeak, Args_&&... args)     {         auto self = selfWeak.lock();         if (!self)             return;          if (!self-&gt;_released) \/\/ AsyncToUiHandlerWrapper \u043d\u0435 \u0431\u044b\u043b \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0451\u043d, \u0437\u043d\u0430\u0447\u0438\u0442, \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 _realHandler, \u0435\u0449\u0451 \u0436\u0438\u0432\u044b             self-&gt;_realHandler(std::forward&lt;Args_&gt;(args)...);     } };   class MediaUiModel : public UiModel&lt;MediaUiModelRow&gt; { private:     using AsyncMediaHandler = AsyncToUiHandlerWrapper&lt;void(const MediaPtr&)&gt;;  private:     std::shared_ptr&lt;AsyncMediaHandler&gt;    _asyncHandler;  public:     MediaUiModel(boost::io_service& uiThread, const MediaScanner& scanner)     {         try         {             _asyncHandler = std::make_shared&lt;AsyncMediaHandler&gt;(std::ref(uiThread), [&](const MediaPtr& m) { this-&gt;AppendRow(MediaUiModelRow(m)); });              std::lock_guard&lt;std::recursive_mutex&gt; l(scanner.GetMutex());              boost::signals2::signal&lt;void(const MediaPtr&)&gt;::slot_type                 slot(std::bind(&AsyncMediaHandler::AsyncHandler&lt;const MediaPtr&&gt;, std::weak_ptr&lt;AsyncMediaHandler&gt;(_asyncHandler), std::placeholders::_1));             slot.track_foreign(_asyncHandler);             scanner.OnMediaFound.connect(slot);              for (auto&& m : scanner.GetMedia())                 AppendRow(MediaUiModelRow(m));         }         catch (...)         {             Destroy();             throw;         }     }      ~MediaUiModel()     { Destroy(); }  private:     void Destroy()     {         if (_asyncHandler)             _asyncHandler-&gt;Release(); \/\/ \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a MediaUiModel \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0440\u0443\u0448\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442         _asyncHandler.reset();     } }; <\/code><\/pre>\n<p>  \u042f \u0434\u0430\u0436\u0435 \u043d\u0435 \u0441\u0442\u0430\u043d\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0433\u0440\u0443\u0441\u0442\u0438\u043c.  <\/div>\n<\/div>\n<p>  <\/p>\n<h3>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435?<\/h3>\n<p>  \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u0430\u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u0447:<\/p>\n<pre><code class=\"cpp\">struct task_executor {     virtual ~task_executor() { }     virtual void add_task(const std::function&lt;void()&gt;& task) = 0; }; <\/code><\/pre>\n<p>  \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <i>connect<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u043e\u0442\u043e\u043a:<\/p>\n<pre><code class=\"cpp\">signal_connection connect(const std::shared_ptr&lt;task_executor&gt;& worker, std::function&lt;Signature&gt; handler); <\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e <i>_handlers<\/i> \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043e\u0431\u0451\u0440\u0442\u043a\u0443 \u043d\u0430\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u0430\u0440\u0443 \u0438\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e <i>life_token::checker<\/i>. \u0414\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <i>execution_guard<\/i> \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u0435\u0442\u043e\u0434 <i>disconnect<\/i> \u043d\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0442\u043e, \u0447\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0442\u043e\u0436\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u0438\u0441\u044c \u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430.<\/p>\n<p>  \u041a\u043e\u0434 \u043e\u0431\u0451\u0440\u0442\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <i>connect<\/i> \u044f \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443. \u0414\u0443\u043c\u0430\u044e, \u0438\u0434\u0435\u044f \u044f\u0441\u043d\u0430 \u0438 \u0442\u0430\u043a.<\/p>\n<p>  \u041a\u043e\u0434 \u043c\u043e\u0434\u0435\u043b\u0438 \u0436\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c:<\/p>\n<pre><code class=\"cpp\">class MediaUiModel : public UiModel&lt;MediaUiModelRow&gt; { private:     signal_connection    _connection;  public:     MediaUiModel(const std::shared_ptr&lt;task_executor&gt;& uiThread, const MediaScanner& scanner)     { _connection = scanner.OnMediaFound.connect(uiThread, [&](const MediaPtr& m) { this-&gt;AppendRow(MediaUiModelRow(m)); }); }      ~MediaUiModel()     { _connection.reset(); } }; <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u0435\u0442\u043e\u0434 <i>AppendRow<\/i> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0432 \u043f\u043e\u0442\u043e\u043a\u0435 UI, \u0438 \u043b\u0438\u0448\u044c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043c\u0441\u044f.<\/p>\n<h1>\u041f\u043e\u0434\u0432\u043e\u0434\u044f \u0438\u0442\u043e\u0433\u0438<\/h1>\n<p>  \u0418\u0442\u0430\u043a, \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432:<\/p>\n<ol>\n<li>\u041f\u043e\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0438\u0433\u043d\u0430\u043b\u0443<\/li>\n<li>\u0411\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <i>disconnect<\/i> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0435\u0433\u043e \u0436\u0435 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435<\/li>\n<li>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0443\u043d\u043a\u0442 \u0431\u044b\u043b \u0432\u0435\u0440\u0435\u043d \u0438 \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, <i>disconnect<\/i> \u0434\u043e\u043b\u0436\u0435\u043d \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043c\u0435\u0447\u0430\u0442\u044c \u0442\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u0430\u043a \u00ab\u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435\u00bb<\/li>\n<\/ol>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u043e\u0434 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0442\u0443\u0442 \u043f\u0440\u0438\u0432\u0451\u043b, \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442 \u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0435\u043d, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e. \u041c\u043e\u0435\u0439 \u0446\u0435\u043b\u044c\u044e \u0431\u044b\u043b\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0447\u0435\u043c \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0441\u0435\u0433\u043e\u0434\u043d\u044f. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0432\u0435\u0449\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435.<\/p>\n<p>  \u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043e\u043a\u043e\u043b\u043e \u043f\u044f\u0442\u0438 \u043b\u0435\u0442, \u0438 \u043e\u0447\u0435\u043d\u044c \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b.<\/p>\n<h2>\u0413\u043e\u0442\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  \u042f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c C++11 \u0441 \u043d\u0443\u043b\u044f \u0442\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u044b, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438, \u0443\u043b\u0443\u0447\u0448\u0438\u043b \u0442\u0435 \u0447\u0430\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u0432\u043d\u043e \u0441\u0442\u043e\u0438\u043b\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c.<br \/>  \u041f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u0441\u044c \u043d\u0430 \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u0435: <a href=\"https:\/\/github.com\/koplyarov\/wigwag\">https:\/\/github.com\/koplyarov\/wigwag<\/a>.<\/p>\n<h2>\u041c\u0438\u043d\u0438-FAQ<\/h2>\n<p>  \u0421\u0443\u0434\u044f \u043f\u043e \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043b\u044e\u0434\u0435\u0439 \u043d\u0430 \u0440\u0435\u0434\u0434\u0438\u0442\u0435 \u0438 \u0432 \u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0435, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0432\u0441\u0435\u0445 \u0432\u043e\u043b\u043d\u0443\u044e\u0442 \u0442\u0440\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u0430:<\/p>\n<p>  <b>Q:<\/b> \u0422\u0443\u0442 \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c life_token \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u044d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e?<br \/>  <b>A:<\/b> \u041a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043d\u0435\u0442. \u041c\u043e\u0436\u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0430 \u0435\u0441\u043b\u0438 \u043c\u044b \u0442\u0430\u043a\u0438 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c <i>disconnect<\/i> \u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f, \u0436\u0434\u0430\u0442\u044c \u043d\u0430 <i>std::condition_variable<\/i>. \u0422\u043e\u0433\u0434\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d: \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043e\u0432\u0435\u0440\u0445\u0435\u0434\u0430 \u0432 \u0432\u0438\u0434\u0435 <i>track<\/i>\/<i>track_foreign<\/i> (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 <i>weak_ptr<\/i>), \u044d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043b\u0435\u043a\u043e \u043f\u043e\u0437\u0430\u0434\u0438 boost::signals2, \u0438 \u0434\u0430\u0436\u0435 \u043e\u043f\u0435\u0440\u0435\u0436\u0430\u0435\u0442 Qt.<br \/>  \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/koplyarov\/wigwag\/wiki\/Benchmarks\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  <b>Q:<\/b> \u041d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 deadlock&#8217;\u043e\u0432 \u0438\u0437-\u0437\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 disconnect?<br \/>  <b>A:<\/b> \u0414\u0430, \u0442\u0443\u0442 deadlock&#8217;\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0443\u0442\u044c \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0432 \u0431\u0443\u0441\u0442\u0435 \u0438 Qt. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e \u043e\u043a\u0443\u043f\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0438 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0438\u0445 \u0440\u0430\u0431\u043e\u0442\u044b. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u0435\u0441\u043b\u0438 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0442\u0435\u043c, \u043a\u0442\u043e \u043d\u0430 \u043a\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d, \u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u2014 \u0441\u043a\u043e\u0440\u0435\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u041d\u0443 \u0438, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e deadlock&#8217;\u0438 \u043d\u0443\u0436\u043d\u043e \u043b\u043e\u0432\u0438\u0442\u044c \u0438 \u0447\u0438\u043d\u0438\u0442\u044c. \u0412 Linux \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e <a href=\"http:\/\/valgrind.org\/docs\/manual\/hg-manual.html\">Helgrind<\/a>. \u0414\u043b\u044f Windows \u0434\u0432\u0443\u0445\u043c\u0438\u043d\u0443\u0442\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a \u0432 \u0433\u0443\u0433\u043b\u0435 \u0434\u0430\u0451\u0442 <a href=\"https:\/\/software.intel.com\/en-us\/intel-inspector-xe\">Intel Inspector<\/a> \u0438 <a href=\"http:\/\/research.microsoft.com\/en-us\/projects\/chess\/\">CHESS<\/a>.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0436\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0435\u0431\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u0437 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0432\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 helgrind \u0438\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0430\u043a\u0430\u044f-\u043d\u0438\u0431\u0443\u0434\u044c \u043c\u0430\u0440\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430), \u0435\u0441\u0442\u044c \u043a\u043e\u0441\u0442\u044b\u043b\u0435\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0433\u043e (\u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e) \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430:<\/p>\n<pre><code class=\"cpp\">class mutex { private:     std::timed_mutex    _m;  public:     void lock()     {         if (_m.try_lock())             return;          while (!_m.try_lock_for(std::chrono::seconds(10)))             Logger::Warning() &lt;&lt; &quot;Could not lock mutex &quot; &lt;&lt; (void*)this &lt;&lt; &quot; for a long time:\\n&quot; &lt;&lt; get_backtrace_string();     }      \/\/ ... }; <\/code><\/pre>\n<p>  \u0418 \u0432 Visual Studio \u0438 \u0432 GCC \u0435\u0441\u0442\u044c \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0442\u0440\u0435\u0439\u0441\u0430 \u0432 \u043a\u043e\u0434\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 libunwind.<br \/>  \u0421 \u044d\u0442\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0430\u0448\u0438\u0445 deadlock&#8217;\u043e\u0432 \u043f\u043e\u0439\u043c\u0430\u044e\u0442 QA, \u0430 \u0432\u044b \u043f\u0440\u0438 \u043e\u0434\u043d\u043e\u043c \u0432\u0437\u0433\u043b\u044f\u0434\u0435 \u043d\u0430 \u043b\u043e\u0433\u0438 \u043f\u043e\u0439\u043c\u0451\u0442\u0435, \u0433\u0434\u0435 \u0432\u0441\u0451 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c. \u041e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0447\u0438\u043d\u0438\u0442\u044c.<\/p>\n<p>  <b>Q:<\/b> \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432? \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u0445\u043e\u0447\u0443? \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e, \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u044b\u0435 \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u044b?<br \/>  <b>A:<\/b> \u041c\u043e\u0436\u043d\u043e, \u043c\u043e\u0436\u043d\u043e, \u043c\u043e\u0436\u043d\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u2014 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.       <\/p>\n<div class=\"clear\"><\/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=\"https:\/\/habrahabr.ru\/post\/279851\/\"> https:\/\/habrahabr.ru\/post\/279851\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0412 \u043c\u0438\u0440\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u0432 C++. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0443 \u0432\u0441\u0435\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u044f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f, \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u0417\u0434\u0435\u0441\u044c \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e\u0431 \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445, \u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-276678","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/276678","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=276678"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/276678\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=276678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=276678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=276678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}