<?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] HTTP Server 3 Beispiel und Sinn von Strands...]]></title><description><![CDATA[<p>Hallo,</p>
<p>Mal eine Frage an boost.asio-Kenner:<br />
Ich bis gerade etwas mit boost.asio am rumbasteln. Im Beispiel <a href="http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3" rel="nofollow">HTTP Server 3</a> wird mit einem Thread-Pool gearbeitet, in dem mehrere Male <code>io_service::run</code> gestartet wird. Man hat dann also mehrere Threads in denen Completion-Handler ausgeführt werden können. Soweit so gut.</p>
<p>Nun gibt es ja noch io_service::strand-Objekte, mit denen man potentiell parallel ablaufende Completion-Handler serialisieren kann. Im oben genannten Beispiel wird das für receive- und write-Handler einer HTTP-Verbindung gemacht.</p>
<p>Mir stellt sich allerdings die Frage: wozu? Ein Completion-Handler wird doch eh erst ausgeführt, wenn die damit Verbundene asynchrone Operation abgeschlossen ist, oder? Die Aufrufreihenfolge sollte also doch per se sequentiell sein.</p>
<p>Hier mal der betreffende Auschnitt aus dem Beispielcode:</p>
<p>Boost.Asio Doku schrieb:</p>
<blockquote>
<pre><code class="language-cpp">oid connection::start()
{
  //wozu hier der strand? Der Completion Handler (also das handle_read weiter unten) wird doch erst aufgerufen, wenn async_read_some abgeschlossen wird, oder?
  socket_.async_read_some(boost::asio::buffer(buffer_),
      strand_.wrap(
        boost::bind(&amp;connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)));
}

void connection::handle_read(const boost::system::error_code&amp; e,
    std::size_t bytes_transferred)
{
  if (!e)
  {
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
        request_, buffer_.data(), buffer_.data() + bytes_transferred);

    if (result)
    {
      request_handler_.handle_request(request_, reply_);
      //siehe oben
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&amp;connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else if (!result)
    {
      reply_ = reply::stock_reply(reply::bad_request);
      //siehe oben
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&amp;connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else
    {
      //siehe oben
      socket_.async_read_some(boost::asio::buffer(buffer_),
          strand_.wrap(
            boost::bind(&amp;connection::handle_read, shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)));
    }
  }
</code></pre>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/topic/256025/boost-asio-http-server-3-beispiel-und-sinn-von-strands</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 06:11:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/256025.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 07 Dec 2009 12:17:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [boost.asio] HTTP Server 3 Beispiel und Sinn von Strands... on Mon, 07 Dec 2009 12:24:48 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>Mal eine Frage an boost.asio-Kenner:<br />
Ich bis gerade etwas mit boost.asio am rumbasteln. Im Beispiel <a href="http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3" rel="nofollow">HTTP Server 3</a> wird mit einem Thread-Pool gearbeitet, in dem mehrere Male <code>io_service::run</code> gestartet wird. Man hat dann also mehrere Threads in denen Completion-Handler ausgeführt werden können. Soweit so gut.</p>
<p>Nun gibt es ja noch io_service::strand-Objekte, mit denen man potentiell parallel ablaufende Completion-Handler serialisieren kann. Im oben genannten Beispiel wird das für receive- und write-Handler einer HTTP-Verbindung gemacht.</p>
<p>Mir stellt sich allerdings die Frage: wozu? Ein Completion-Handler wird doch eh erst ausgeführt, wenn die damit Verbundene asynchrone Operation abgeschlossen ist, oder? Die Aufrufreihenfolge sollte also doch per se sequentiell sein.</p>
<p>Hier mal der betreffende Auschnitt aus dem Beispielcode:</p>
<p>Boost.Asio Doku schrieb:</p>
<blockquote>
<pre><code class="language-cpp">oid connection::start()
{
  //wozu hier der strand? Der Completion Handler (also das handle_read weiter unten) wird doch erst aufgerufen, wenn async_read_some abgeschlossen wird, oder?
  socket_.async_read_some(boost::asio::buffer(buffer_),
      strand_.wrap(
        boost::bind(&amp;connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)));
}

void connection::handle_read(const boost::system::error_code&amp; e,
    std::size_t bytes_transferred)
{
  if (!e)
  {
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
        request_, buffer_.data(), buffer_.data() + bytes_transferred);

    if (result)
    {
      request_handler_.handle_request(request_, reply_);
      //siehe oben
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&amp;connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else if (!result)
    {
      reply_ = reply::stock_reply(reply::bad_request);
      //siehe oben
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&amp;connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else
    {
      //siehe oben
      socket_.async_read_some(boost::asio::buffer(buffer_),
          strand_.wrap(
            boost::bind(&amp;connection::handle_read, shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)));
    }
  }
</code></pre>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1818983</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1818983</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Mon, 07 Dec 2009 12:24:48 GMT</pubDate></item><item><title><![CDATA[Reply to [boost.asio] HTTP Server 3 Beispiel und Sinn von Strands... on Fri, 06 Aug 2010 13:27:00 GMT]]></title><description><![CDATA[<p>Ganze 8 Monate später...<br />
Habe beim rumgooglen deine Frage gefunden, vor die ich mich auch konfrontiert sah...</p>
<p>Das sehe ich ganz genau so. Die Reihefolge ist hier eh sequentiell.</p>
<p>So wie ich das sehe ist das srand Objekt nur der Besitzer des connection Objekts (einziger der noch einen shared_ptr auf connection besitzt). Dies hatte im Beispiel <a href="http://boost-sandbox.sourceforge.net/boost_1_43_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server" rel="nofollow">Http Server</a> die Klasse connection_container erledigt.</p>
<p>Wird der letzte Completion-Handler verlassen, terminiert srand und damit der letzte shared_ptr auf connection und somit connection selbst...<br />
(siehe quellcode-kommentare am ende von connection::handle_read und connection::handle_write)</p>
<p>Grüße.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1937115</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1937115</guid><dc:creator><![CDATA[Ka55i0peia]]></dc:creator><pubDate>Fri, 06 Aug 2010 13:27:00 GMT</pubDate></item></channel></rss>