<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie?]]></title><description><![CDATA[<p>Ich versuch mich mal kurz zu fassen, ohne wichtige Details auszulassen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<pre><code class="language-cpp">class ServerEvent;
class Communicator
{
  typedef std::function&lt;void(ServerEvent const&amp;)&gt; Callback;

  Callback cb;

  Communicator(Callback const&amp; c)
    : cb(c)
  {}

  void send(ServerEvent const&amp; evt) const
  {
    cb(evt);
  }
};

class Server
{
  Communicator&amp; comm;

  boost::asio::io_service ioService;
  std::unique_ptr&lt;boost::asio::io_service::work&gt; work;
  std::unique_ptr&lt;boost::thread&gt; serverThread;

public:
  Server(Communicator const&amp; c)
    : comm(c)
    , ioService()
    , work(new boost::asio::io_service::work(ioService))
    , serverThread(new boost::thread([this](){ioService.run();})
  {}

  ~Server()
  {
    work.reset(); //don't keep the service running
    serverThread-&gt;join();
  }

  void sendClientEvent(ClientEvent const&amp; evt)
  {
    ioService.post([this, evt](){processEvent(evt);});
  }

  void processEvent(ClientEvent const&amp; evt)
  {
    /* ... */
    comm.send(/* some ServerEvent here */);
    /* ... */
  }
};
</code></pre>
<p>Soviel zum Aufbau, der Server soll quasi ein Active Object sein, dem bei der Konstruktion ein Callback für die von ihm erzeugten Events übergeben wird und der die ClientEvents in seinem internen Thread asynchron verarbeitet.<br />
(Wenns Anmerkungen/Verbesserungsvorschläge zum Design gibt bzgl. asio/threads, immer her damit!)<br />
Nun zu meinem Problem:</p>
<pre><code class="language-cpp">void some_test_function()
{
  Communicator comm([&amp;](ServerEvent const&amp;)
    {
      foo();
    });

  {
     Server srv(comm);
     srv.sendClientEvent(/* some ClientEvent here */);
  }
}
</code></pre>
<p>Meinem naiven Verständnis zufolge, was der Compiler beim Code-Erzeugen verschieben darf und was nicht, würde ich annehmen, dass der Server auf jeden Fall vor dem Communicator zerstört wird. Ich habe jetzt aber im Debugger mehrfach access violations gehabt, weil im Serverthread auf den Communicator zugegriffen wurde, der garnicht mehr existierte. Wieso das?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/291999/boost-asio-boost-thread-c-0x-lambdas-reordering-über-scope-grenzen-hinweg-oder-wie</link><generator>RSS for Node</generator><lastBuildDate>Mon, 17 Aug 2026 08:32:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/291999.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 31 Aug 2011 20:11:29 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 20:14:40 GMT]]></title><description><![CDATA[<p>Ich versuch mich mal kurz zu fassen, ohne wichtige Details auszulassen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<pre><code class="language-cpp">class ServerEvent;
class Communicator
{
  typedef std::function&lt;void(ServerEvent const&amp;)&gt; Callback;

  Callback cb;

  Communicator(Callback const&amp; c)
    : cb(c)
  {}

  void send(ServerEvent const&amp; evt) const
  {
    cb(evt);
  }
};

class Server
{
  Communicator&amp; comm;

  boost::asio::io_service ioService;
  std::unique_ptr&lt;boost::asio::io_service::work&gt; work;
  std::unique_ptr&lt;boost::thread&gt; serverThread;

public:
  Server(Communicator const&amp; c)
    : comm(c)
    , ioService()
    , work(new boost::asio::io_service::work(ioService))
    , serverThread(new boost::thread([this](){ioService.run();})
  {}

  ~Server()
  {
    work.reset(); //don't keep the service running
    serverThread-&gt;join();
  }

  void sendClientEvent(ClientEvent const&amp; evt)
  {
    ioService.post([this, evt](){processEvent(evt);});
  }

  void processEvent(ClientEvent const&amp; evt)
  {
    /* ... */
    comm.send(/* some ServerEvent here */);
    /* ... */
  }
};
</code></pre>
<p>Soviel zum Aufbau, der Server soll quasi ein Active Object sein, dem bei der Konstruktion ein Callback für die von ihm erzeugten Events übergeben wird und der die ClientEvents in seinem internen Thread asynchron verarbeitet.<br />
(Wenns Anmerkungen/Verbesserungsvorschläge zum Design gibt bzgl. asio/threads, immer her damit!)<br />
Nun zu meinem Problem:</p>
<pre><code class="language-cpp">void some_test_function()
{
  Communicator comm([&amp;](ServerEvent const&amp;)
    {
      foo();
    });

  {
     Server srv(comm);
     srv.sendClientEvent(/* some ClientEvent here */);
  }
}
</code></pre>
<p>Meinem naiven Verständnis zufolge, was der Compiler beim Code-Erzeugen verschieben darf und was nicht, würde ich annehmen, dass der Server auf jeden Fall vor dem Communicator zerstört wird. Ich habe jetzt aber im Debugger mehrfach access violations gehabt, weil im Serverthread auf den Communicator zugegriffen wurde, der garnicht mehr existierte. Wieso das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113193</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113193</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 31 Aug 2011 20:14:40 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 20:51:30 GMT]]></title><description><![CDATA[<p>Mal janz doof jefracht: was passiert wenn man in ner Lambda-Expression eine Referenz &quot;by value&quot; captured? Tut die dann zu &quot;T&quot; zerfallen, oder bleibt sie &quot;T&amp;&quot;?<br />
Falls zweiteres (was ich annehme, hab aber nicht nachgeguckt) hast du ein Problem in sendClientEvent() (bzw. später, wenn die gepostete Lambda-Expression aufgerufen werden tut).</p>
<blockquote>
<p>auto _=[](){}; //WTF?</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113202</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113202</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 31 Aug 2011 20:51:30 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 20:59:27 GMT]]></title><description><![CDATA[<p>Oder am besten gleich:</p>
<pre><code class="language-cpp">[](){[](){}();}();
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2113204</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113204</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Wed, 31 Aug 2011 20:59:27 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 21:45:41 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Mal janz doof jefracht: was passiert wenn man in ner Lambda-Expression eine Referenz &quot;by value&quot; captured? Tut die dann zu &quot;T&quot; zerfallen, oder bleibt sie &quot;T&amp;&quot;?<br />
Falls zweiteres (was ich annehme, hab aber nicht nachgeguckt) hast du ein Problem in sendClientEvent() (bzw. später, wenn die gepostete Lambda-Expression aufgerufen werden tut).</p>
</blockquote>
<p>Zweiteres, und ich habe das Problem nicht, weil ich in sendClientEvent evt explizit per value capture.</p>
<p>Es wird grade immer wilder: Ich habe den Communicator jetzt in einen shared_ptr gehängt und der Server hält ihn intern nicht per referenz, sondern einen weak_ptr. Beim weak_ptr.lock() sollte ich dann ja einen shared_ptr auf den communicator oder auf nichts bekommen - stattdessen gibts eine access-violation. Ich versuch das die Tage mal zu isolieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113216</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113216</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 31 Aug 2011 21:45:41 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 22:21:46 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Mal janz doof jefracht: was passiert wenn man in ner Lambda-Expression eine Referenz &quot;by value&quot; captured? Tut die dann zu &quot;T&quot; zerfallen, oder bleibt sie &quot;T&amp;&quot;?<br />
Falls zweiteres (was ich annehme, hab aber nicht nachgeguckt) hast du ein Problem in sendClientEvent() (bzw. später, wenn die gepostete Lambda-Expression aufgerufen werden tut).</p>
</blockquote>
<p>Zweiteres, und ich habe das Problem nicht, weil ich in sendClientEvent evt explizit per value capture.</p>
</blockquote>
<p>Nö, ersteres. Aber ja, genau deswegen ist das kein Problem.<br />
Innerhalb der Lambda-Expression ist &quot;evt&quot; keine Referenz mehr sondern eine Kopie (Zumindest macht das MSVC so). Das meinte ich mit &quot;zu T zerfallen&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113221</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113221</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 31 Aug 2011 22:21:46 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Wed, 31 Aug 2011 22:58:11 GMT]]></title><description><![CDATA[<p>Also mit deinem Beispielcode kann ich das Problem nicht nachvollziehen... läuft (nach Korrekturen von ein paar Tippfehlern) perfekt (MSVC 10, Debug &amp; Release, x64, Windows 7).</p>
<p>ps: <a href="http://ideone.com" rel="nofollow">ideone.com</a> kann ja leider <em>entweder</em> boost <em>oder</em> C++0x, aber leider nicht beides zusammen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113224</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113224</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 31 Aug 2011 22:58:11 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio, boost.thread, C++0x.Lambdas] Reordering über Scope-Grenzen hinweg oder wie? on Fri, 02 Sep 2011 12:17:44 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Nö, ersteres. Aber ja, genau deswegen ist das kein Problem.</p>
</blockquote>
<p>Gnarf. Ja. Capture by value/reference ist analog zu call by value/reference, eben so, dass by value eine Kopie des Objektes anlegt, by reference eine Referenz darauf, ganz egal ob das, was &quot;übergeben&quot; wird, nun eine Referenz oder das Objekt selbst ist.</p>
<p>ZUm problem: Ich vermute, dass es irgendwelche Interferenzen mit dem turtle.mock Framework gegeben hat. Ich hatte dem Communicator einen MOCK_FUNCTOR übergeben, das ist ihm wohl irgendwie nicht bekommen. Ich versuche, da weiter ein Auge drauf zu haben. Trotzdem wäre es klasse, wenn die Multithreading-Gurus hier sich das grundsätzliche Design mal zu Gemüte führen können und mir sagen, wenn es da was zu verbessern gibt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2113862</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2113862</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 02 Sep 2011 12:17:44 GMT</pubDate></item></channel></rss>