Wie erkenne ich, ob std::async einen extra Thread erzeugt oder nicht?



  • Konkretes Beispiel:

    #include <iostream>
    #include <future>
    #include <thread>
    #include <chrono>
    #include <string>
    
    using namespace std;
    
    ////////////////////////////////////////////////////////////////////////////////////
    // async should be the first choice. Threads are started and managed during runtime.
    
    auto sleep = [](int s) { this_thread::sleep_for(chrono::seconds(s)); };
    
    int provideTheNumberForEverything(int sec)
    {
            sleep (sec);
            return 42;
    }
    
    int main()
    {
        auto start_time = chrono::high_resolution_clock::now();
    
        ////////////////////////////////////////////////////////////////////////////////
        // future from an async()
        ////////////////////////////////////////////////////////////////////////////////
    
        auto result1 = async( /*launch::async,*/ &provideTheNumberForEverything, 3);
        // future<int> result1 = async(/*launch::async*/, &provideTheNumberForEverything,3);
        // future<int> result1 = async(/*launch::async*/, [](){ sleep(3); return 42; });
    
        ////////////////////////////////////////////////////////////////////////////////
        // future from a packaged_package
        ////////////////////////////////////////////////////////////////////////////////
    
        packaged_task<string()> package([](){ sleep(5); return "The number"; }); 
        future<string> result2 = package.get_future();  
        thread(move(package)).detach(); 
    
        ////////////////////////////////////////////////////////////////////////////////
        // future from a promise
        ////////////////////////////////////////////////////////////////////////////////
    
        promise<string> p;
        future<string> result3 = p.get_future();
        thread(  [](promise<string> p)
                 { 
                   sleep(7); p.set_value_at_thread_exit("is the answer to everything."); 
                 }, 
                 move(p)
               ).detach();
    
        //////////////////////////////// output ////////////////////////////////////////
    
        cout << "Waiting... " << endl;
        result1.wait();
        auto end_time = chrono::high_resolution_clock::now();
        cout << "result 1 ... time: " << chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() << " ms" << endl;
        result2.wait();
        end_time = chrono::high_resolution_clock::now();
        cout << "result 2 ... time: " << chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() << " ms" << endl;
        result3.wait();
        end_time = chrono::high_resolution_clock::now();
        cout << "result 3 ... time: " << chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() << " ms" << endl;
        cout << "\nDone!\nResults are: " << result2.get() << ' ' << result1.get() << ' ' << result3.get() << '\n';
    }
    

    Mit std::launch::async kann ich einen Extra-Thread erzwingen, mit std::launch::deferred einen unterdrücken. Wie ist das, wenn ich nichts angebe, es also C++ zur laufzeit überlasse? Wie erkenne ich, ob std::async zur Laufzeit einen extra Thread erzeugt oder nicht?



  • 1. Warum willst Du das ueberhaupt wissen?

    2. Async duerfte in den allermeisten Faellen die falsche Wahl sein. Schreib dir lieber nen Thread-Pool oder so.



  • Async duerfte in den allermeisten Faellen die falsche Wahl sein.

    async ist erste Wahl (R. Grimm, C++11 für Programmierer, Praxistipp)

    Warum willst Du das ueberhaupt wissen?

    Aus Interesse.



  • Erhard Henkes schrieb:

    Mit std::launch::async kann ich einen Extra-Thread erzwingen, mit std::launch::deferred einen unterdrücken.

    Erzwingen und unterdrücken sind IMHO nicht ganz richtig.

    http://en.cppreference.com/w/cpp/thread/async schrieb:

    Behaves the same as async(std::launch::async | std::launch::deferred, f, args...). In other words, f may be executed in another thread or it may be run synchronously when the resulting std::future is queried for a value.

    für async ohne Angaben.

    Erhard Henkes schrieb:

    Wie ist das, wenn ich nichts angebe, es also C++ zur laufzeit überlasse? Wie erkenne ich, ob std::async zur Laufzeit einen extra Thread erzeugt oder nicht?

    - Debugger
    - Top
    - Threadids ausgeben lassen



  • Erhard Henkes schrieb:

    async ist erste Wahl (R. Grimm, C++11 für Programmierer, Praxistipp)

    Und weil's in einem Buch steht, muss es richtig sein?



  • cooky451 schrieb:

    2. Async duerfte in den allermeisten Faellen die falsche Wahl sein.

    Warum?

    cooky451 schrieb:

    Schreib dir lieber nen Thread-Pool oder so.

    So ganz trivial dürfte das selber schreiben aber auch nicht sein. Ob das wirklich jeder machen sollte?



  • Ich wiederhole die Frage, auf deren klare Beantwortung ich noch warte:

    Wie erkenne ich, ob std::async zur Laufzeit einen extra Thread erzeugt oder nicht?



  • Erhard Henkes schrieb:

    Ich wiederhole die Frage, auf deren klare Beantwortung ich noch warte:

    Wie erkenne ich, ob std::async zur Laufzeit einen extra Thread erzeugt oder nicht?

    Lesen hilft



  • Ueberpruefen, ob gerade in einem anderen Thread laeuft, wird mit der thread id gehen. Von aussen geht das wohl kaum zuverlaessig.

    std::async ist in der theorie ganz gut, weil die library auf weitere Informationen, im Prinzip sogar auf codelaengenabschaetzung, zurueckgreifen koennte. Praktisch sind die aber oft ganz primitiv implementiert mit "starte es deferred, wenn nicht anders angegeben" (gcc), sodass eine implementierung per threadpool oft deutlich schneller ist.

    haskell und go zeigen, wie es sein koennte.



  • Yep.

    - Debugger
    - Top
    - Threadids ausgeben lassen


Log in to reply