<?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-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe folgendes Problem bei dem Einsatz von Boost-Threads. Ich erstelle 4 Threads, die gemeinsam auf eine Liste zugreifen sollen. Hierzu habe ich einen globalen Index, der von jedem Thread inkrementiert werden kann und mit dem sich ein Thread ein Element aus der Liste zur Abarbeitung holen kann. Sowohl die Inkrementierung des Index', als auch die Abfrage des aktuellen Elements aus der Liste, befinden sich in einem geschützten Bereich. Alle Threads werden in einer Thread-Group zusammen gepackt und dann durch den Aufruf join_all() gestartet. Beim ersten Durchlauf scheinen alle Threads in etwa gleichzeitig in den geschützten Bereich zu gelangen bevor ein Thread den Bereich für die anderen blockieren kann. Das hat zur Folge, dass mehrmals das Element an Stelle 0 der Liste bearbeitet wird. Bei allen folgenden Durchläufen funktioniert die Sperre des geschützten Bereichs ohne Probleme. Gibt es eventuell eine Möglichkeit die Threads etwas zeitversetzt zu starten oder gibt es andere Lösungswege?</p>
<p>Abschließend stelle ich noch die entsprechenden Codeschnipsel zur Verfügung:</p>
<p>Erstellen der Thread-Group und starten der Threads:</p>
<pre><code>boost::thread_group group;
for (int i = 0; i &lt; NUM_THREADS; i++) {
    boost::thread *thread = new boost::thread(&amp;ReportBuilder::loadFoils, this);
    group.add_thread(thread);
}
group.join_all();
</code></pre>
<p>Aufgerufene Methode der Threads mit Aufruf des geschützten Bereichs:</p>
<pre><code>void ReportBuilder::loadFoils() {
    Statistics stat;
    for (foilListCounter = 0; foilListCounter &lt; foilList.size();) {
        SmallFoilInfo inf = getFoilInfo();
        stat.loadFoil(inf, false);
    }
}
</code></pre>
<p>Aufgerufener geschützter Bereich:</p>
<pre><code>SmallFoilInfo ReportBuilder::getFoilInfo() {
    boost::mutex::scoped_lock lock(mutex);
    int index = foilListCounter;
    cout &lt;&lt; &quot;index: &quot; &lt;&lt; index &lt;&lt; endl;
    SmallFoilInfo info = foilList[index];
    foilListCounter++;
    return info;
}
</code></pre>
<p>Ausgabe der Konsole:</p>
<pre><code>index: 0
index: 0
index: 0
index: 1
index: 2
index: 3
index: 4
index: 5
index: 6
</code></pre>
<p>Vielen Dank im Voraus!</p>
<p>Gruß,<br />
Sven</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/319249/boost-threads-laufen-bei-erstem-durchlauf-gleichzeitig-in-geschützten-bereich</link><generator>RSS for Node</generator><lastBuildDate>Sat, 25 Jul 2026 23:55:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/319249.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 12 Aug 2013 09:39:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Boost-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich on Mon, 12 Aug 2013 09:39:35 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe folgendes Problem bei dem Einsatz von Boost-Threads. Ich erstelle 4 Threads, die gemeinsam auf eine Liste zugreifen sollen. Hierzu habe ich einen globalen Index, der von jedem Thread inkrementiert werden kann und mit dem sich ein Thread ein Element aus der Liste zur Abarbeitung holen kann. Sowohl die Inkrementierung des Index', als auch die Abfrage des aktuellen Elements aus der Liste, befinden sich in einem geschützten Bereich. Alle Threads werden in einer Thread-Group zusammen gepackt und dann durch den Aufruf join_all() gestartet. Beim ersten Durchlauf scheinen alle Threads in etwa gleichzeitig in den geschützten Bereich zu gelangen bevor ein Thread den Bereich für die anderen blockieren kann. Das hat zur Folge, dass mehrmals das Element an Stelle 0 der Liste bearbeitet wird. Bei allen folgenden Durchläufen funktioniert die Sperre des geschützten Bereichs ohne Probleme. Gibt es eventuell eine Möglichkeit die Threads etwas zeitversetzt zu starten oder gibt es andere Lösungswege?</p>
<p>Abschließend stelle ich noch die entsprechenden Codeschnipsel zur Verfügung:</p>
<p>Erstellen der Thread-Group und starten der Threads:</p>
<pre><code>boost::thread_group group;
for (int i = 0; i &lt; NUM_THREADS; i++) {
    boost::thread *thread = new boost::thread(&amp;ReportBuilder::loadFoils, this);
    group.add_thread(thread);
}
group.join_all();
</code></pre>
<p>Aufgerufene Methode der Threads mit Aufruf des geschützten Bereichs:</p>
<pre><code>void ReportBuilder::loadFoils() {
    Statistics stat;
    for (foilListCounter = 0; foilListCounter &lt; foilList.size();) {
        SmallFoilInfo inf = getFoilInfo();
        stat.loadFoil(inf, false);
    }
}
</code></pre>
<p>Aufgerufener geschützter Bereich:</p>
<pre><code>SmallFoilInfo ReportBuilder::getFoilInfo() {
    boost::mutex::scoped_lock lock(mutex);
    int index = foilListCounter;
    cout &lt;&lt; &quot;index: &quot; &lt;&lt; index &lt;&lt; endl;
    SmallFoilInfo info = foilList[index];
    foilListCounter++;
    return info;
}
</code></pre>
<p>Ausgabe der Konsole:</p>
<pre><code>index: 0
index: 0
index: 0
index: 1
index: 2
index: 3
index: 4
index: 5
index: 6
</code></pre>
<p>Vielen Dank im Voraus!</p>
<p>Gruß,<br />
Sven</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2345179</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2345179</guid><dc:creator><![CDATA[Sven F.]]></dc:creator><pubDate>Mon, 12 Aug 2013 09:39:35 GMT</pubDate></item><item><title><![CDATA[Reply to Boost-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich on Mon, 12 Aug 2013 09:52:04 GMT]]></title><description><![CDATA[<p>Der Fehler liegt in dieser Zeile:</p>
<pre><code class="language-cpp">for (foilListCounter = 0; foilListCounter &lt; foilList.size();) {
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2345182</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2345182</guid><dc:creator><![CDATA[_fool_]]></dc:creator><pubDate>Mon, 12 Aug 2013 09:52:04 GMT</pubDate></item><item><title><![CDATA[Reply to Boost-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich on Mon, 12 Aug 2013 10:06:25 GMT]]></title><description><![CDATA[<p>Alles klar, das habe ich völlig übersehen. Die Variable wurde also immer wieder mit 0 am Anfang einer Schleife initialisiert und daher die Überschneidung. Habe das ganze nun durch folgende Zeile ersetzt und es wird genau das getan, was ich erwarte:</p>
<pre><code>while (foilListCounter &lt; foilList.size()) {
</code></pre>
<p>Vielen Dank für die schnelle Hilfe!</p>
<p>Gruß,<br />
Sven</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2345188</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2345188</guid><dc:creator><![CDATA[Sven F.]]></dc:creator><pubDate>Mon, 12 Aug 2013 10:06:25 GMT</pubDate></item><item><title><![CDATA[Reply to Boost-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich on Mon, 12 Aug 2013 10:54:47 GMT]]></title><description><![CDATA[<p>Das ist aber auch falsch, weil ints lesen ist nicht atomar (der foilListCounter könnte ausgelesen werden während ein anderer Thread foilListCounter++ ausführt)</p>
<p>Die Sofortlösung wäre</p>
<pre><code class="language-cpp">SmallFoilInfo ReportBuilder::getFoilInfo(int&amp; index) {
    boost::mutex::scoped_lock lock(mutex);
    index = foilListCounter;
    cout &lt;&lt; &quot;index: &quot; &lt;&lt; index &lt;&lt; endl;
    SmallFoilInfo info = foilList[index];
    foilListCounter++;
    return info;
}

void ReportBuilder::loadFoils() {
    Statistics stat;
    int counter;
    for (SmallFoilInfo inf = getFoilInfo(counter); counter&lt;foilList.size(); inf = getFoilInfo(counter)) {
        stat.loadFoil(inf, false);
    }
}
</code></pre>
<p>Allgemein besser wäre eine lock-free Implementierung.</p>
<pre><code class="language-cpp">atomic&lt;int&gt; foilListCounter; // als Member (oder size_t)

bool ReportBuilder::getFoilInfo(SmallFoilInfo inf) {
    int index = foilListCounter.fetch_add(1); // threadsafe counter++
    if (index &gt;= foilList.size())
        return false;
    inf = foilList[index];
    return true;
}

void ReportBuilder::loadFoils() {
    Statistics stat;
    for (SmallFoilInfo inf; getFoilInfo(inf);) {
        stat.loadFoil(inf, false);
    }
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2345196</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2345196</guid><dc:creator><![CDATA[_fool_]]></dc:creator><pubDate>Mon, 12 Aug 2013 10:54:47 GMT</pubDate></item><item><title><![CDATA[Reply to Boost-Threads laufen bei erstem Durchlauf gleichzeitig in geschützten Bereich on Mon, 12 Aug 2013 10:56:00 GMT]]></title><description><![CDATA[<p>natürlich <code>bool ReportBuilder::getFoilInfo(SmallFoilInfo&amp; inf)</code></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2345197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2345197</guid><dc:creator><![CDATA[_fool_]]></dc:creator><pubDate>Mon, 12 Aug 2013 10:56:00 GMT</pubDate></item></channel></rss>