<?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 Problem]]></title><description><![CDATA[<p>Hallo</p>
<p>Sieht jemand was ich hier falsch mache? io_service::run() ist ja angeblich von mehreren Threads aufrufbar. Ich möchte dass jeder Thread eine bestimmte Anzahl von Warteoperationen hintereinander ausführt (zu Testzwecken), später möchte ich diese durch schreib- und Leseoperationen ersetzen. Das schreiben und Lesen auf ein Socket soll dann parallel ablaufen. Aber offenbar gibts hier ein Problem dass jeder Thread run() nur einmal ausführen kann.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;boost/asio.hpp&gt;

boost::mutex m;

class Thread
{
    boost::asio::io_service* m_io;
    boost::asio::strand m_strand;
    char* m_name;
    int m_n;
    int m_t;

    public:

        Thread(char* name, int n, int t, boost::asio::io_service&amp; io): m_io(&amp;io), m_strand(io),
            m_name(name), m_n(n), m_t(t)
        {
        }

        void Handler(const boost::system::error_code&amp; ec)
        {
            boost::lock_guard&lt;boost::mutex&gt; lock(::m);

            if(ec)
            {
                std::cout &lt;&lt; ec.message() &lt;&lt; '\n';
            }
            else
            {
                std::cout &lt;&lt; m_name &lt;&lt; '\n';
            }
        }

        void operator ()()
        {
            boost::asio::deadline_timer t(*m_io);

            for(int i = 0; i &lt; m_n; ++i)
            {
                t.expires_from_now(boost::posix_time::milliseconds(m_t));
                t.async_wait(m_strand.wrap(boost::bind(&amp;Thread::Handler, this, _1)));
                m_io-&gt;run();
            }
        }
};

int main()
{
    try
    {
        boost::asio::io_service io;

        boost::thread t1(Thread(&quot;T1&quot;, 10, 1000, io));
        boost::thread t2(Thread(&quot;T2&quot;, 5, 2000, io));
        boost::thread t3(Thread(&quot;T3&quot;, 3, 3000, io));

        t1.join();
        t2.join();
        t3.join();
    }
    catch(std::exception &amp;e)
    {
        std::cout &lt;&lt; e.what();
    }

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/276187/boost-asio-problem</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 11:47:35 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/276187.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 28 Oct 2010 14:05:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:05:35 GMT]]></title><description><![CDATA[<p>Hallo</p>
<p>Sieht jemand was ich hier falsch mache? io_service::run() ist ja angeblich von mehreren Threads aufrufbar. Ich möchte dass jeder Thread eine bestimmte Anzahl von Warteoperationen hintereinander ausführt (zu Testzwecken), später möchte ich diese durch schreib- und Leseoperationen ersetzen. Das schreiben und Lesen auf ein Socket soll dann parallel ablaufen. Aber offenbar gibts hier ein Problem dass jeder Thread run() nur einmal ausführen kann.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;boost/asio.hpp&gt;

boost::mutex m;

class Thread
{
    boost::asio::io_service* m_io;
    boost::asio::strand m_strand;
    char* m_name;
    int m_n;
    int m_t;

    public:

        Thread(char* name, int n, int t, boost::asio::io_service&amp; io): m_io(&amp;io), m_strand(io),
            m_name(name), m_n(n), m_t(t)
        {
        }

        void Handler(const boost::system::error_code&amp; ec)
        {
            boost::lock_guard&lt;boost::mutex&gt; lock(::m);

            if(ec)
            {
                std::cout &lt;&lt; ec.message() &lt;&lt; '\n';
            }
            else
            {
                std::cout &lt;&lt; m_name &lt;&lt; '\n';
            }
        }

        void operator ()()
        {
            boost::asio::deadline_timer t(*m_io);

            for(int i = 0; i &lt; m_n; ++i)
            {
                t.expires_from_now(boost::posix_time::milliseconds(m_t));
                t.async_wait(m_strand.wrap(boost::bind(&amp;Thread::Handler, this, _1)));
                m_io-&gt;run();
            }
        }
};

int main()
{
    try
    {
        boost::asio::io_service io;

        boost::thread t1(Thread(&quot;T1&quot;, 10, 1000, io));
        boost::thread t2(Thread(&quot;T2&quot;, 5, 2000, io));
        boost::thread t3(Thread(&quot;T3&quot;, 3, 3000, io));

        t1.join();
        t2.join();
        t3.join();
    }
    catch(std::exception &amp;e)
    {
        std::cout &lt;&lt; e.what();
    }

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1971960</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971960</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:05:35 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:23:19 GMT]]></title><description><![CDATA[<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>io_service::run() ist ja angeblich von mehreren Threads aufrufbar.</p>
</blockquote>
<p>Wie kommst du auf diese Idee? Das wäre mir ganz neu.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1971970</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971970</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:23:19 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:30:50 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>io_service::run() ist ja angeblich von mehreren Threads aufrufbar.</p>
</blockquote>
<p>Wie kommst du auf diese Idee? Das wäre mir ganz neu.</p>
<p>Grüssli</p>
</blockquote>
<p>Aus der Doku:</p>
<blockquote>
<p>Multiple threads may call io_service::run() to set up a pool of threads from which completion handlers may be invoked. This approach may also be used with io_service::post() to use a means to perform any computational tasks across a thread pool.</p>
</blockquote>
<p><a href="http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/overview/core/threads.html" rel="nofollow">http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/overview/core/threads.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1971973</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971973</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:30:50 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:44:51 GMT]]></title><description><![CDATA[<p>Was ich letztendlich erreichen will ist simultanes schreiben und lesen auf einem Socket, ohne dass das eine das andere blockiert. Also, ein Thread sendet Daten, der andere empfängt. Falls jemand weiss wie man das mit boost::asio realisieren kann, wäre ich dankbar für einen Tipp.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1971977</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971977</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:44:51 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:48:41 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>io_service::run() ist ja angeblich von mehreren Threads aufrufbar.</p>
</blockquote>
<p>Wie kommst du auf diese Idee? Das wäre mir ganz neu.</p>
<p>Grüssli</p>
</blockquote>
<p>Das ist sogar die Idee... der Fall, dass run(..) nur von einem Thread aus aufgerufen wird ist eher ein spezial Fall.</p>
<p>Die Idee ist, dass alle Threads, die run(..) aufrufen zum Thread Pool gehören (implizit). Handler werden dann auf einem dieser Threads aufgerufen.</p>
<p>Mit io_service::strand können die Handler aufrufe serialisiert werden.</p>
<p>Simon</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1971979</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971979</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:48:41 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 14:50:41 GMT]]></title><description><![CDATA[<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>Was ich letztendlich erreichen will ist simultanes schreiben und lesen auf einem Socket, ohne dass das eine das andere blockiert. Also, ein Thread sendet Daten, der andere empfängt. Falls jemand weiss wie man das mit boost::asio realisieren kann, wäre ich dankbar für einen Tipp.</p>
</blockquote>
<p>Du benutzt einfach async_write(..) und async_read(..) und fertig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1971983</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1971983</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Thu, 28 Oct 2010 14:50:41 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 15:29:02 GMT]]></title><description><![CDATA[<p>Man lernt immer wieder was neues. Aber eine geile Sache! Ich glaube sogar, dass ich das in einem konkreten zukünftigen Projekt gebrauchen könnte *Notiz macht* <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>
<p>Und wo liegt hier jetzt das Problem oder ist das nun beseitigt? Die Problembeschreibung ist ja nicht wirklich berauschend <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>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972004</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972004</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 28 Oct 2010 15:29:02 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Thu, 28 Oct 2010 16:08:55 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>: Kompiliere dir doch den Code oben <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="😉"
    /> Dann sag mir was die Fehlermeldungen verursacht.</p>
<p>Ich wollte eben zuerst paralleles Warten ausprobieren (anstatt lesen und Schreiben), weil mir das Protokoll noch fehlt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972030</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Thu, 28 Oct 2010 16:08:55 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Fri, 29 Oct 2010 06:29:16 GMT]]></title><description><![CDATA[<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>Dann sag mir was die Fehlermeldungen verursacht.</p>
</blockquote>
<p>Welche Fehlermeldung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972203</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972203</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Fri, 29 Oct 2010 06:29:16 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Fri, 29 Oct 2010 07:05:35 GMT]]></title><description><![CDATA[<p>Also erstmal:<br />
Wieso ein <code>strand</code> -Objekt <em>und</em> ein Mutex? Das <code>strand</code> -Objekt soll ja gerade explizites Verriegeln überflüssig machen. Du brauchst also nicht noch zusätzlich einen Mutex.</p>
<p>Zweitens:</p>
<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>Aber offenbar gibts hier ein Problem dass jeder Thread run() nur einmal ausführen kann.</p>
</blockquote>
<p>Da ist auch so. Jeder Thread in dem <code>io_service::run</code> ausgeführt wird stellt eine eigenständige Queue zur asynchronen Verarbeitung dar. Damit ist der Thread dann vollzeitbeschäftigt.</p>
<p>Dein Handler kann allerdings durch den Stand (und den Mutex) nur jeweils in einem Thread gleichzeitig ausgeführt werden.</p>
<p>PS: Dein <code>deadline_timer</code> lebt nicht lange genug:</p>
<pre><code class="language-cpp">void operator ()()
{
    //hier legst Du ihn als auto-Variable an.
    boost::asio::deadline_timer t(*m_io);

    for(int i = 0; i &lt; m_n; ++i)
    {
        t.expires_from_now(boost::posix_time::milliseconds(m_t));

        t.async_wait(m_strand.wrap(boost::bind(&amp;Thread::Handler, this, _1)));
        m_io-&gt;run();
    }
    //hier, also beim Verlassen der Funktion stirbt Dein Timer
    //(während er auf den Timeout wartet)
    //der Handler wird dadurch abgeschossen,
    //so als wenn man cancel() aufruft. Daher die &quot;Fehlermeldung&quot;.
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1972207</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972207</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Fri, 29 Oct 2010 07:05:35 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Fri, 29 Oct 2010 09:52:18 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/4465">@Tachyon</a>:<br />
Der mutex ist nur für std::cout, das von verschiedenen Threads benutzt wird. Ansonsten müsste ich wohl für alle Handler die std::cout benutzen den gleichen strand nehemen. Es ist doch so dass alle Handler, die in den gleichen Strand gewrapt wurden, in dem Thread ausgeführt werden, in dem das Strand-Objekt erzeugt wurde. Oder habe ich das falsch verstanden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972273</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972273</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Fri, 29 Oct 2010 09:52:18 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Fri, 29 Oct 2010 11:13:08 GMT]]></title><description><![CDATA[<p><strong>Stefan</strong> schrieb:</p>
<blockquote>
<p>[...]Es ist doch so dass alle Handler, die in den gleichen Strand gewrapt wurden, in dem Thread ausgeführt werden, in dem das Strand-Objekt erzeugt wurde. Oder habe ich das falsch verstanden?</p>
</blockquote>
<p>Das <code>strand</code> -Objekt wurde ja nicht in einem Thread erzeugt, sondern er benutzt ein <code>io_service</code> -Objekt. Wenn die <code>run</code> -Methode des <code>io_service</code> -Objektes in mehreren Threads ausgeführt wird, dann können Handler, die in dem <code>io_service</code> hängen normalerweise parallel ausgeführt werden. Von allen Handlern, die in einen strand gepackt werden, kann jeweils nur noch einer zur Zeit aktiv sein. Alle anderen müssen warten, bis der gerade aktive Handler fertig ist.</p>
<p>Beispiel:<br />
Du hast einen TCP-Server, der asynchron Verbindungen annehmen kann ( <code>async_accept</code> ). Jede erfolgreich angenommene Verbindung soll zur weiteren Verarbeitung in einen Container gelegt werden. Damit Dein Server besser skaliert, hast Du nun die <code>run</code> -Methode des <code>io_service</code> -Objektes auf dem <code>async_accept</code> arbeitet in mehreren Threads gestartet. Dadurch können nun mehrere <code>connect</code> -Anfragen zur gleichen Zeit behandelt werden. Das heisst dann auch, dass mehrere <code>accept</code> -Handler versuchen können, die Verbindungen in den Container einzutragen. Wenn der nicht threadsafe ist, dann knallt es. Wenn Du den <code>accept</code> -Handler nun in einen <code>strand</code> wickelst, wird kann nur jeweils ein Handler zur Zeit ausgeführt werden. Es geht bei einem <code>strand</code> also darum, dass von verschiedenen Threads, welche in den durch den <code>strand</code> geschützten Bereich eintreten wollen nur jeweils einer aktiv sein darf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972297</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Fri, 29 Oct 2010 11:13:08 GMT</pubDate></item><item><title><![CDATA[Reply to boost::asio Problem on Fri, 29 Oct 2010 11:32:22 GMT]]></title><description><![CDATA[<p>Ok, das ist nachvollziehbar. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1972300</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1972300</guid><dc:creator><![CDATA[__Stefan__]]></dc:creator><pubDate>Fri, 29 Oct 2010 11:32:22 GMT</pubDate></item></channel></rss>