<?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[Verwaltung mehrerer Threads]]></title><description><![CDATA[<p>Hallo,<br />
ich möchte mir in C++ ein Programm schreiben, was Rechenaufgaben mittels der C++11 Threads auf meine Kerne vereilt.<br />
Ein Threadverwalter prüft, ob CPU Kerne unbelegt sind und ob Noch Berechnungen anstehen und spwant Threads.<br />
Bedauerlicherweise funktioniert meine Implementation nicht. Hat jemand eine Idee, warum die Anwendung immer nur einen Thread erzeugt, anstatt 4?</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstring&gt;
#include &lt;future&gt;
#include &lt;vector&gt;

void workThread(const uint64_t&amp; seed) {

    // Logistische Gleichung berechen
    uint64_t numIterations = 1000000000 * (1 + rand() % 3);
    double xn = 0;
    double a = 4.0 * ((double) seed / 1000000.0);
    for(uint64_t i = 0; i &lt; numIterations; ++ i) {
        xn = a * xn * (1.0 + xn);
    }

    std::cout &lt;&lt; xn;
}

class Scheduler {
private:
    uint32_t numThreads = 0;

    std::vector&lt;bool&gt; threadStates;
    std::vector&lt;std::thread&gt; threads;

    bool haveTasks = true;
    uint64_t activeThreads = 0;
    const uint64_t seedStart = 0;
    const uint64_t seedEnd = 1000000;
    uint64_t seed = seedStart;

public:
    Scheduler() {
        numThreads = std::thread::hardware_concurrency();

        for(uint64_t i = 0; i &lt; numThreads; ++ i) {
            threads.push_back(std::thread());
            threadStates.push_back(0);
        }

        activeThreads = 0;

    }

    void sheduleThreads() {

        while(haveTasks) {
            // Threads spawnen
            while(activeThreads &lt; numThreads) {
                for(uint64_t t = 0; t &lt; numThreads; ++ t) {
                    if(threadStates[t] == false) {
                        threads[t] = std::thread(workThread, seed);
                        seed ++;
                        activeThreads ++;
                        threadStates[t] = true;

                        std::async(std::launch::async, [this](uint64_t t){ std::cout &lt;&lt; &quot;join: &quot; &lt;&lt; t &lt;&lt; std::endl; this-&gt;threads[t].join(); }, t);
                        break;
                    }
                }
            }

            // Pruefen, ob noch Seeds vorhanden
            if(seed &gt;= seedEnd) {
                haveTasks = false;
            }

            // Status der Threads pruefen
            for(uint64_t t = 0; t &lt; numThreads; ++ t) {
                if(!threads[t].joinable()) {
                    activeThreads --;
                    threadStates[t] = false;
                } else {
                    threadStates[t] = true;
                }
            }

//            std::cout &lt;&lt; &quot;active threads: &quot; &lt;&lt; activeThreads &lt;&lt; std::endl;
            std::cout &lt;&lt; 100.0 * (double) seed / (double) seedEnd &lt;&lt; std::endl;
        }
    }

};

using namespace std;

int main() {
    Scheduler sh;
    sh.sheduleThreads();
    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/327417/verwaltung-mehrerer-threads</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Jul 2026 07:12:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/327417.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 10 Aug 2014 18:13:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 18:13:15 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich möchte mir in C++ ein Programm schreiben, was Rechenaufgaben mittels der C++11 Threads auf meine Kerne vereilt.<br />
Ein Threadverwalter prüft, ob CPU Kerne unbelegt sind und ob Noch Berechnungen anstehen und spwant Threads.<br />
Bedauerlicherweise funktioniert meine Implementation nicht. Hat jemand eine Idee, warum die Anwendung immer nur einen Thread erzeugt, anstatt 4?</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstring&gt;
#include &lt;future&gt;
#include &lt;vector&gt;

void workThread(const uint64_t&amp; seed) {

    // Logistische Gleichung berechen
    uint64_t numIterations = 1000000000 * (1 + rand() % 3);
    double xn = 0;
    double a = 4.0 * ((double) seed / 1000000.0);
    for(uint64_t i = 0; i &lt; numIterations; ++ i) {
        xn = a * xn * (1.0 + xn);
    }

    std::cout &lt;&lt; xn;
}

class Scheduler {
private:
    uint32_t numThreads = 0;

    std::vector&lt;bool&gt; threadStates;
    std::vector&lt;std::thread&gt; threads;

    bool haveTasks = true;
    uint64_t activeThreads = 0;
    const uint64_t seedStart = 0;
    const uint64_t seedEnd = 1000000;
    uint64_t seed = seedStart;

public:
    Scheduler() {
        numThreads = std::thread::hardware_concurrency();

        for(uint64_t i = 0; i &lt; numThreads; ++ i) {
            threads.push_back(std::thread());
            threadStates.push_back(0);
        }

        activeThreads = 0;

    }

    void sheduleThreads() {

        while(haveTasks) {
            // Threads spawnen
            while(activeThreads &lt; numThreads) {
                for(uint64_t t = 0; t &lt; numThreads; ++ t) {
                    if(threadStates[t] == false) {
                        threads[t] = std::thread(workThread, seed);
                        seed ++;
                        activeThreads ++;
                        threadStates[t] = true;

                        std::async(std::launch::async, [this](uint64_t t){ std::cout &lt;&lt; &quot;join: &quot; &lt;&lt; t &lt;&lt; std::endl; this-&gt;threads[t].join(); }, t);
                        break;
                    }
                }
            }

            // Pruefen, ob noch Seeds vorhanden
            if(seed &gt;= seedEnd) {
                haveTasks = false;
            }

            // Status der Threads pruefen
            for(uint64_t t = 0; t &lt; numThreads; ++ t) {
                if(!threads[t].joinable()) {
                    activeThreads --;
                    threadStates[t] = false;
                } else {
                    threadStates[t] = true;
                }
            }

//            std::cout &lt;&lt; &quot;active threads: &quot; &lt;&lt; activeThreads &lt;&lt; std::endl;
            std::cout &lt;&lt; 100.0 * (double) seed / (double) seedEnd &lt;&lt; std::endl;
        }
    }

};

using namespace std;

int main() {
    Scheduler sh;
    sh.sheduleThreads();
    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2412870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412870</guid><dc:creator><![CDATA[chingchangchui]]></dc:creator><pubDate>Sun, 10 Aug 2014 18:13:15 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 18:46:04 GMT]]></title><description><![CDATA[<p>Unmittelbares Problem ist, dass</p>
<pre><code class="language-cpp">std::async(std::launch::async, [this](uint64_t t) {
                                   std::cout &lt;&lt; &quot;join: &quot; &lt;&lt; t &lt;&lt; std::endl;
                                   this-&gt;threads[t].join();
                                 },
             t);
</code></pre>
<p>nicht asynchron ist (der Destruktor der future &quot;joint&quot; die Berechnung).</p>
<p>Warum aber überhaupt den ganzen Overhead?</p>
<pre><code class="language-cpp">#include &lt;boost/range/irange.hpp&gt;
#include &lt;boost/range/algorithm/for_each.hpp&gt;

int main() {
  const unsigned seedStart = 0;
  const unsigned seedEnd = 1000000;
  const unsigned numTasks = 100 * std::thread::hardware_concurrency();
  const unsigned workSize = (seedEnd - seedStart + numTasks - 1) / numTasks;
  std::vector&lt;std::future&lt;void&gt; &gt; tasks;
  for (unsigned i : boost::irange(seedStart, seedEnd, workSize))
    tasks.push_back(std::async([=] {
      boost::for_each(boost::irange(i, std::min(i + workSize, seedEnd)),
                      workThread);
    }));
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2412872</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412872</guid><dc:creator><![CDATA[async!=async]]></dc:creator><pubDate>Sun, 10 Aug 2014 18:46:04 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 18:58:46 GMT]]></title><description><![CDATA[<p>Hervorragend für die schnelle Antwort!</p>
<p>Wie kann ich</p>
<pre><code>tasks.push_back(std::async([=] {
      boost::for_each(boost::irange(i, std::min(i + workSize, seedEnd)),
                      workThread);
    }));
</code></pre>
<p>ohne Boost realisieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2412874</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412874</guid><dc:creator><![CDATA[chingchangchui]]></dc:creator><pubDate>Sun, 10 Aug 2014 18:58:46 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 19:02:20 GMT]]></title><description><![CDATA[<p>Ist nur ein fancy way um eine for-Loop zu schreiben.</p>
<pre><code class="language-cpp">for (unsigned i=seedStart; i&lt;seedEnd; i += workSize)
  tasks.push_back(std::async([=] {
        for (unsigned j=i; j&lt;std::min(i + workSize, seedEnd); ++j)
          workThread(j);
  }));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2412875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412875</guid><dc:creator><![CDATA[async!=async]]></dc:creator><pubDate>Sun, 10 Aug 2014 19:02:20 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 19:41:39 GMT]]></title><description><![CDATA[<p>Mit folgendem Code passiert gar nichts mehr Oo</p>
<pre><code>void workThread(const uint64_t&amp; seed) {

    // Logistische Gleichung berechen
    uint64_t numIterations = 1000;
    double xn = 1.0;
    const double a = 4.0 * ((double) seed / 1000000.0);
    for(uint64_t i = 0; i &lt; numIterations; ++ i) {
        xn = a * xn * (1.0 + xn);
    }

    std::cout &lt;&lt; &quot;xn: &quot; &lt;&lt; xn &lt;&lt; std::endl;
}

int main() {
  const uint64_t seedStart = 0;
  const uint64_t seedEnd = 100000000;
  const uint64_t numTasks = std::thread::hardware_concurrency();

  const uint64_t workSize = (seedEnd - seedStart + numTasks - 1) / numTasks;
  std::cout &lt;&lt; &quot;worksize: &quot; &lt;&lt; workSize &lt;&lt; std::endl;
  std::vector&lt;std::future&lt;void&gt; &gt; tasks;
  for(uint64_t seed = seedStart; seed &lt; seedEnd; seed += workSize) {
    tasks.push_back(std::async([=] {
        for(uint64_t t = 0; t &lt; std::min(t + workSize, seedEnd); ++ t) {
            workThread(t);
        }
    }));
  }

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2412885</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412885</guid><dc:creator><![CDATA[chingchangchui]]></dc:creator><pubDate>Sun, 10 Aug 2014 19:41:39 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Sun, 10 Aug 2014 20:00:43 GMT]]></title><description><![CDATA[<p>Ja, sorry, hätte es testen sollen. Füg nach der Schleife noch ein</p>
<pre><code class="language-cpp">for (auto&amp; f : tasks)
    f.get();
</code></pre>
<p>an, ich dachte das passiere automatisch.</p>
<p>Btw, du hast meinen Code verschlimmbessert. numTask sollte um einen konstanten Faktor grösser sein als die Anzahl logischer Cores (10 oder 100 ist da gut geeignet), uint64_t ist für std::thread::hardware_concurrency() der falsche Typ und was die innere for-Loop bei dir machen soll verstehe ich nicht (kurz: sie ist falsch).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2412888</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412888</guid><dc:creator><![CDATA[async!=async]]></dc:creator><pubDate>Sun, 10 Aug 2014 20:00:43 GMT</pubDate></item><item><title><![CDATA[Reply to Verwaltung mehrerer Threads on Mon, 11 Aug 2014 09:15:26 GMT]]></title><description><![CDATA[<p>@Ja, sorry, hätte es testen sollen. Füg nach der Schleife noch ein<br />
Leider hatte ich hier kein Erfolg</p>
<pre><code>int main()
{
    const uint64_t seedStart = 0;
    const uint64_t seedEnd = 1000000;
    const uint64_t numTasks = 100 * std::thread::hardware_concurrency();

    const uint64_t workSize = (seedEnd - seedStart + numTasks - 1) / numTasks;
    std::cout &lt;&lt; &quot;worksize: &quot; &lt;&lt; workSize &lt;&lt; std::endl;
    std::vector&lt;std::future&lt;void&gt; &gt; tasks;
    for(uint64_t seed = seedStart; seed &lt; seedEnd; seed += workSize)
    {
        tasks.push_back(std::async([=]
        {
            for(uint64_t t = 0; t &lt; std::min(t + workSize, seedEnd); ++ t)
            {
                workThread(t);
            }
        }));
    }

    for (auto&amp; f : tasks)
    {
        f.get();
    }

    return 0;
}
</code></pre>
<p>@Btw, du hast meinen Code verschlimmbessert. numTask sollte um einen konstanten Faktor grösser sein als die Anzahl logischer Cores (10 oder 100 ist da gut geeignet), uint64_t ist für std::thread::hardware_concurrency() der falsche Typ und was die innere for-Loop bei dir machen soll verstehe ich nicht (kurz: sie ist falsch).<br />
Bezieht sich das auf folgende Schleife?</p>
<pre><code>for(uint64_t t = 0; t &lt; std::min(t + workSize, seedEnd); ++ t) {
            workThread(t);
        }
</code></pre>
<p>Mein Ziel:<br />
Ich habe ein Problem, welches in Teilprobleme zerlegen kann.<br />
Jedes Teilproblem kann durch den Seed beschrieben werden.<br />
Das Programm soll solange n Prozesse spawnen, bis alle Probleme gelöst sind / keine Seeds mehr vorhanden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2412955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2412955</guid><dc:creator><![CDATA[chingchangchui]]></dc:creator><pubDate>Mon, 11 Aug 2014 09:15:26 GMT</pubDate></item></channel></rss>