{"id":201388,"date":"2013-11-15T10:00:03","date_gmt":"2013-11-15T06:00:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=201388"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=201388","title":{"rendered":"<span class=\"post_title\">\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u0438\u0441\u043a \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a<\/span>"},"content":{"rendered":"<div class=\"content html_format\"> \t\t\t\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043d\u0430\u0447\u0430\u043b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430. \u041f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430 \u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0438 \u043a\u0430\u043a-\u0442\u043e \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043a\u043e \u043c\u043d\u0435 \u043f\u043e\u0434\u043a\u0440\u0430\u043b\u0438\u0441\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438. \u042f \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u043b \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u2014 \u044d\u0442\u043e <b>\u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438<\/b>. \u041f\u043e \u043d\u0435\u0437\u043d\u0430\u043d\u0438\u044e \u043e\u0441\u043d\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u044f \u043d\u0435\u044f\u0432\u043d\u043e \u043d\u0430\u0440\u0443\u0448\u0438\u043b \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a. \u041d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0411\u043e\u0440\u0436\u043e\u043c\u0438 \u043f\u0438\u0442\u044c \u043f\u043e\u0437\u0434\u043d\u043e, \u043f\u0440\u0438\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0430\u0441\u0447\u0451\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0442\u044f\u0436\u0435\u043b\u0443\u044e \u0430\u0440\u0442\u0438\u043b\u043b\u0435\u0440\u0438\u044e.<br \/>  <a name=\"habracut\"><\/a><br \/>  <img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/388\/bf3\/cba\/388bf3cba77d1715e0c9387dae92cc8e.jpg\"\/><br \/>  \u0418\u0442\u0430\u043a, \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 (\u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434):  <\/p>\n<pre><code class=\"cpp\">object m1; object m2;  \/\/ thread 1 quard&lt;&gt; g1(m1); .... \/\/ \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f m2 \u043f\u043e\u0442\u043e\u043a\u043e\u043c thread 2  quard&lt;&gt; g2(m2);  \/\/ thread 2 quard&lt;&gt; g2(m2); .... \/\/ \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f m2 \u043f\u043e\u0442\u043e\u043a\u043e\u043c thread 1 quard&lt;&gt; g1(m1);  <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0431\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438\u043b\u0438 \u0432 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e.  <\/p>\n<h4>\u0418\u0434\u0435\u044f.<\/h4>\n<p>  \u041f\u0443\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0440\u0430\u0444 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u044d\u0442\u043e \u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u043e\u043c\u0430\u044f \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430.<br \/>  \u041f\u0440\u0438\u043c\u0435\u0440:<br \/>  \u0433\u0434\u0435 \u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u043f\u043e\u0442\u043e\u043a\u0430: guard(m1) &#8212;&gt; guard(m2)<br \/>  \u0433\u0434\u0435 \u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u043f\u043e\u0442\u043e\u043a\u0430: guard(m2) &#8212;&gt; guard(m1)!!! alarm!!! \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430.<\/p>\n<h4>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h4>\n<p>  \u0414\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0440\u0430\u0444\u043e\u0432 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0442\u044f\u0436\u043a\u043e. \u042f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u00abboost\/graph\u00bb.<br \/>  \u0414\u043b\u044f \u0443\u0447\u0451\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 DLL \u2014 \u00abboost\/interprocess\u00bb. <br \/>  \u0420\u0430\u0441\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043c\u044b\u0441\u043b\u0430 \u043d\u0435\u0442. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0443\u043d\u043a\u0442\u044b:  <\/p>\n<ul>\n<li> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0441\u0432\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a, \u0434\u043b\u044f \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0435\u043d\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a <\/li>\n<li>\u0433\u0440\u0430\u0444 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430<\/li>\n<\/ul>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e:  <\/p>\n<pre><code class=\"cpp\">#define ENABLE_DEADLOCK_CHECKER \/**\/ #include &quot;deadlock_checker.h&quot; \/*\u043a\u043b\u0430\u0441\u0441 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430*\/ class guard {      guard()   {     deadlock_checker_t::push(this);   }      ~guard()   {     deadlock_checker_t::pop(this);   }  }; <\/code><\/pre>\n<p>  P.S. \u0412\u0441\u0451 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u043e\u0441\u044c \u0445\u043e\u0440\u043e\u0448\u043e. \u042f \u043e\u0442\u043b\u043e\u0432\u0438\u043b deadlock. \u041f\u043e\u0437\u043d\u0430\u043b \u0434\u0430\u043e \u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b \u043c\u043e\u0434\u0443\u043b\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0437\u0430 \u043d\u0435\u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\"> \/* *\t\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u0438\u0441\u043a  \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0437\u0430\u0438\u043c\u043e- \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a.  *\/ #pragma once #include &lt;assert.h&gt; #include &lt;stack&gt; #include &lt;map&gt; #include &lt;vector&gt; #include &lt;boost\/thread\/mutex.hpp&gt; #include &lt;boost\/thread\/tss.hpp&gt; #include &lt;boost\/thread\/once.hpp&gt; #include &lt;boost\/graph\/adjacency_list.hpp&gt; #include &lt;boost\/graph\/depth_first_search.hpp&gt; #include &lt;boost\/graph\/visitors.hpp&gt; #include &lt;boost\/filesystem.hpp&gt; #include &lt;boost\/interprocess\/managed_shared_memory.hpp&gt; #ifdef _DEBUG \/\/#define ENABLE_DEADLOCK_CHECKER #endif namespace deadlock_checker {      inline unsigned long get_current_process_id()     {           return GetCurrentProcessId();      }      template&lt;typename T&gt;     struct deadlock_graph_i     {         virtual bool _cdecl insert(const void* locker_child, const void* locker_root) = 0;     };     \/***\/     template&lt;typename T&gt;     class deadlock_graph : public deadlock_graph_i&lt;T&gt;     {         struct cycle_detector : public ::boost::dfs_visitor&lt;&gt;         {             cycle_detector(bool& has_cycle)                  : m_has_cycle(has_cycle) { }              template &lt;class Edge, class Graph&gt;             void back_edge(Edge, Graph&) { m_has_cycle = true;              }         protected:             bool& m_has_cycle;         };         typedef ::boost::adjacency_list&lt;::boost::mapS, ::boost::mapS, ::boost::bidirectionalS,             ::boost::property&lt;::boost::vertex_color_t, ::boost::default_color_type&gt; &gt; Graph;         typedef typename ::boost::graph_traits&lt;Graph&gt;::vertex_descriptor vertex_descriptor;         typedef typename ::boost::graph_traits&lt;Graph&gt;::edge_descriptor edge_descriptor;         typedef const void* type_value;     public:         ::boost::mutex _mutex;          Graph _graph;         ::std::map&lt;type_value, vertex_descriptor&gt; _vertex;         \/\/std::vector &lt; ::boost::default_color_type &gt; _color_map;     public:         deadlock_graph()         {         }         \/***\/         bool _cdecl insert(const void* locker_child, const void* locker_root)         {             using namespace ::boost;             using namespace ::std;             mutex::scoped_lock scoped_lock(_mutex);              if(_vertex.end() == _vertex.find(locker_child))             {                 _vertex.insert(make_pair(locker_child, add_vertex(_graph) ));             }              if(_vertex.end() == _vertex.find(locker_root))             {                 _vertex.insert(make_pair(locker_root, add_vertex(_graph) ));             }             vertex_descriptor vertex_child = _vertex[locker_child];             pair&lt;edge_descriptor, bool&gt; ret = add_edge(vertex_child,_vertex[locker_root],_graph);             if(ret.second)             {                 bool has_cycle = false;                 cycle_detector vis(has_cycle);                 \/\/_color_map.resize(num_vertices(_graph)); \/\/= color_map(num_vertices(_graph));                 \/\/::std::fill(_color_map.begin(),_color_map.end(),white_color);                  graph_traits&lt;Graph&gt;::vertex_iterator vi, vi_end;                 for (tie(vi, vi_end) = vertices(_graph); vi != vi_end; ++vi)                     get(vertex_color, _graph)[*vi] = white_color;                  depth_first_visit(_graph, vertex_child, vis,                     get(vertex_color, _graph) );                 if(has_cycle)                 {                     \/\/ \u0437\u0430\u0447\u0438\u0449\u0430\u0435\u043c \u0433\u0440\u0430\u0444, \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0437\u0430\u043d\u043e\u0432\u043e.                     _graph.clear();                     _vertex.clear();                  }                 return !has_cycle;             }             return true;         }      };     inline char const* deadlock_shared_key()     {         return &quot;1958EF20-6689-4e7b-9C53-3C115BCCF465&quot;;     }     \/***\/     template&lt;typename T&gt;     class deadlock_graph_common     {         deadlock_graph&lt;T&gt; _graph;         deadlock_graph_i&lt;T&gt;* _graph_ptr;         \/\/ \u0444\u043b\u0430\u0433 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f         bool _graph_main;     public:         deadlock_graph_common()             : _graph_main(false)             , _graph_ptr(NULL)         {             using namespace boost::interprocess;             char process_id_str[20];             if(0 != _itoa_s(GetCurrentProcessId(),process_id_str,boost::size(process_id_str),10))             {                 throw ::std::runtime_error(&quot;error itoa()&quot;);             };              managed_shared_memory shmem(open_or_create, deadlock_shared_key(), 1024);                 _graph_ptr = *shmem.find_or_construct&lt;deadlock_graph&lt;T&gt;*&gt;(process_id_str)(&_graph);             _graph_main = _graph_ptr == &_graph;         }         ~deadlock_graph_common()         {             using namespace boost::interprocess;             try             {                 if(_graph_main)                 {                     char process_id_str[20];                     if(0 == _itoa_s(GetCurrentProcessId(),process_id_str,sizeof(process_id_str),10))                     {                         managed_shared_memory shmem(open_only, deadlock_shared_key());                             shmem.destroy&lt;deadlock_graph&lt;T&gt;*&gt;(process_id_str);                     };                  }             }             catch(...)             {             }         }         deadlock_graph_i&lt;T&gt;* operator-&gt;()         {             return _graph_ptr;         }     };     \/**\u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0433\u0440\u0430\u0444*\/     template&lt;typename T&gt;     class main     {         deadlock_graph&lt;T&gt; _graph;     public:         main()         {             using namespace boost::interprocess;             char process_id_str[20];             if(0 != _itoa_s(get_current_process_id(),process_id_str,sizeof(process_id_str),10))             {                 throw ::std::runtime_error(__FUNCTION__);             }              managed_shared_memory shmem(open_or_create, deadlock_shared_key(), 1024);                 shmem.construct&lt;deadlock_graph&lt;T&gt;*&gt;(process_id_str)(&_graph);          }     };     \/**\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441*\/     template&lt;typename T&gt;     class checker     {     private:         \/**\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0433\u0440\u0430\u0444.*\/         struct main_ref         {             deadlock_graph_i&lt;T&gt;* & _graph_ptr;         public:             main_ref(deadlock_graph_i&lt;T&gt;* & graph_ptr)                 : _graph_ptr(graph_ptr)             {             }             void operator()() const             {                 using namespace boost::interprocess;                 char process_id_str[20];                 if(0 != _itoa_s(get_current_process_id(),process_id_str,boost::size(process_id_str),10))                 {                     throw ::std::runtime_error(__FUNCTION__);                 }                 managed_shared_memory shmem(open_read_only, deadlock_shared_key());                     _graph_ptr = *shmem.find&lt;deadlock_graph&lt;T&gt;*&gt;(process_id_str).first;                 if(!_graph_ptr)                 {                     throw ::std::runtime_error(__FUNCTION__);                 }             }         };     private:         static boost::thread_specific_ptr&lt;::std::stack&lt;void*&gt; &gt; _stack;         static deadlock_graph_i&lt;T&gt;* _graph_ptr;         static boost::once_flag     _graph_flag;     public:         static bool push(T* locker, char* name)         {             if(!push(locker))             {                 \/\/ \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0437\u0438\u043c\u043e-\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443.                 if(::boost::filesystem::file_exist())                 {                 }             }         }         \/***\/         static bool push(void* locker)         {             bool cycle_error = false;             init_thread();             ::std::stack&lt;void*&gt;* lockers = _stack.get();             assert(lockers && lockers-&gt;size() &lt; 8);             if(lockers-&gt;size() &gt; 0)             {                 void* locker_root = lockers-&gt;top();                 if(locker_root != locker)                 {                     \/\/ \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0437\u0430\u0438\u043c\u043e-\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443.                     char const * filename = &quot;.\\\\Data\\\\deadlock.log&quot;;                     if(!::boost::filesystem::is_regular_file(filename))                     {                         \/\/ \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0435\u0431\u0440\u043e \u0432 \u0433\u0440\u0430\u0444.                         cycle_error = !_graph_ptr-&gt;insert(locker,locker_root);                         assert(!cycle_error && &quot;\u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 deadlock&quot;);                         if(cycle_error)                         {                             ::std::ofstream file(filename);                             if(file.is_open())                             {                                 file &lt;&lt; &quot;\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 deadlock&quot; &lt;&lt; ::std::endl;                             }                         }                     }                 }             }             lockers-&gt;push(locker);             return cycle_error;         };         \/***\/         static void pop(void* locker = 0)         {             ::std::stack&lt;void*&gt;* lockers = _stack.get();             assert(lockers && !lockers-&gt;empty());             assert(!locker || lockers-&gt;top() == locker);             if(!lockers-&gt;empty())             {                 lockers-&gt;pop();             };         };     private:         \/***\/         static void init_thread()         {             if(!_stack.get())             {                 boost::call_once(_graph_flag, main_ref(_graph_ptr));                 _stack.reset(new ::std::stack&lt;T*&gt;);             }         }     };       template&lt;typename T&gt;     boost::thread_specific_ptr&lt;::std::stack&lt;void*&gt; &gt; checker&lt;T&gt;::_stack;     template&lt;typename T&gt;     deadlock_graph_i&lt;T&gt;* checker&lt;T&gt;::_graph_ptr;     template&lt;typename T&gt;     boost::once_flag       checker&lt;T&gt;::_graph_flag;      template&lt;&gt;     class checker&lt;bool&gt;     {     public:         static bool push(void* \/*locker*\/, char* \/*name*\/)         {             return true;         }         \/***\/         static bool push(void* \/*locker*\/)         {             return true;         };         \/***\/         static void pop(void* \/*locker*\/ = 0)         {         };     };     template&lt;&gt;     class main&lt;bool&gt;     {     }; }  #if defined(ENABLE_DEADLOCK_CHECKER) typedef deadlock_checker::checker&lt;void&gt; deadlock_checker_t; typedef deadlock_checker::main&lt;void&gt; deadlock_checker_main_t; #else typedef deadlock_checker::checker&lt;bool&gt; deadlock_checker_t; typedef deadlock_checker::main&lt;bool&gt; deadlock_checker_main_t; #endif  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/201388\/\"> http:\/\/habrahabr.ru\/post\/201388\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\"> \t\t\t\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043d\u0430\u0447\u0430\u043b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430. \u041f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430 \u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0438 \u043a\u0430\u043a-\u0442\u043e \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043a\u043e \u043c\u043d\u0435 \u043f\u043e\u0434\u043a\u0440\u0430\u043b\u0438\u0441\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438. \u042f \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u043b \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u2014 \u044d\u0442\u043e <b>\u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438<\/b>. \u041f\u043e \u043d\u0435\u0437\u043d\u0430\u043d\u0438\u044e \u043e\u0441\u043d\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u044f \u043d\u0435\u044f\u0432\u043d\u043e \u043d\u0430\u0440\u0443\u0448\u0438\u043b \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a. \u041d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0411\u043e\u0440\u0436\u043e\u043c\u0438 \u043f\u0438\u0442\u044c \u043f\u043e\u0437\u0434\u043d\u043e, \u043f\u0440\u0438\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0430\u0441\u0447\u0451\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0442\u044f\u0436\u0435\u043b\u0443\u044e \u0430\u0440\u0442\u0438\u043b\u043b\u0435\u0440\u0438\u044e.  <\/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-201388","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/201388","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=201388"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/201388\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=201388"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=201388"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=201388"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}