Home Dashboard Directory Help
Search

std::async(std::launch::async, ...) does not behave as std::thread(...) by Petke Himself


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 735731
Opened: 4/5/2012 10:55:35 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

I noticed something surprising with std::async.

According to http://en.cppreference.com/w/cpp/thread/async

"If policy & std::launch::async != 0 (the async bit is set), spawns a new thread of execution as if by std::thread(f, args...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller."

However in my app using std::async(std::launch::async, ...) does not behave as std::thread(...).

In my app I have twenty very expensive network calls that block for 10 seconds. I used to do them one after another, which added up to 200s. I changed to using std::thread(...), and now they all executed at the same time in 10s. I then changed to std::async(std::launch::async, ... ) and now it would take about 50s. As in some calls would only start after others had completed. This was surprising to me. And I wonder if its not a bug. I tried it on both windows 8 and windows 2008 SP2. Behaves the same. So async looks a bit lazy even if you tell it to do std::launch::async.


Unfortunately I dont have a toy example to show you but I got this pseudocode:

Thanks /Petke

        <fast code>
        std::vector<std::thread> threadVec;

        std::for_each(thingVec.begin(), thingVec.end(), [&](const Thing& thing) {

            auto thread = std::thread([=]() {
                
                try {

                    std::cout << "thread start id: " << std::this_thread::get_id() << std::endl;
                    VeryExpensiveBlockingNetworkCall(thing);
                    std::cout << "thread done id: " << std::this_thread::get_id() << std::endl;

                } catch(std::exception& exc) {
                    std::cout << "Thread Exception: " << exc.what() << std::endl;
                } catch(...) {
                    std::cout << "Thread Uknwon Exception: " << std::endl;
                }
            });

            threadVec.push_back(std::move(thread));
        });

        std::for_each(threadVec.begin(), threadVec.end(), [&](std::thread& thread) {
            try {
                std::cout << "join start" << std::endl;
                thread.join();
                std::cout << "join done" << std::endl;
            } catch(std::exception& exc) {
                std::cout << "Async Exception: " << exc.what() << std::endl;
            }

        });
        </fast code>

        <slow code>
        std::vector<std::future<void>> futVec;
        
        std::for_each(thingVec.begin(), thingVec.end(), [&](const Thing& thing) {

            auto fut = std::async(std::launch::async, [=]() {
                
                std::cout << "thread start id: " << std::this_thread::get_id() << std::endl;
                VeryExpensiveBlockingNetworkCall(thing);
                std::cout << "thread done id: " << std::this_thread::get_id() << std::endl;
            });

            futVec.push_back(std::move(fut));
        });
        
        std::for_each(futVec.begin(), futVec.end(), [&](std::future<void>& fut) {
            
            try {
                std::cout << "wait start" << std::endl;
                fut.wait();
                std::cout << "wait done" << std::endl;
            } catch(std::exception& exc) {
                std::cout << "Async Exception: " << exc.what() << std::endl;
            }

        });        
        
        </slow code>



Details
Sign in to post a comment.
Posted by Microsoft on 4/27/2012 at 9:37 PM
Hi,

Thanks for reporting this bug. We've fixed it, and the fix will be available in VC11 RTM.

The following example demonstrates the fix (hopefully Connect will let me paste it all at once):

C:\Temp>type meow.cpp
#include <stdio.h>
#include <algorithm>
#include <atomic>
#include <future>
#include <iomanip>
#include <random>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
using namespace std;

int main() {
    const thread::id main_id = this_thread::get_id();

    const auto orig = []() -> vector<unsigned int> {
        mt19937 prng(1729);

        vector<unsigned int> v(1000000);

        for (auto& e : v) {
            e = prng();
        }

        return v;
    }();

    for (int mode = 0; mode < 3; ++mode) {
        puts("-----");

        auto policy = launch::async;

        switch (mode) {
        case 0:
            puts("launch::async | launch::deferred");
            policy = launch::async | launch::deferred;
            break;

        case 1:
            puts("launch::async");
            policy = launch::async;
            break;

        case 2:
            puts("launch::deferred");
            policy = launch::deferred;
            break;

        default:
            puts("UH OH");
            break;
        }

        vector<future<void>> futures;

        atomic<bool> atom(false);

        int concurrent = 0;

        for (int i = 0; i < 50; ++i) {
            futures.push_back(async(policy,
                [i, &main_id, &atom, &concurrent, &orig]() {
                    const thread::id this_id = this_thread::get_id();

                    string s;

                    if (this_id == main_id) {
                        s = "on MAIN thread";
                    } else {
                        ostringstream oss;
                        oss << "on thread " << setw(4) << this_id;
                        s = oss.str();
                    }

                    bool b;

                    while (!(b = false, atom.compare_exchange_weak(b, true))) { }
                    printf("future %2d starting (%s). Concurrent futures: %d\n", i, s.c_str(), ++concurrent);
                    atom.store(false);

                    for (int k = 0; k < 4; ++k) {
                        auto v = orig;
                        sort(v.begin(), v.end());
                    }

                    while (!(b = false, atom.compare_exchange_weak(b, true))) { }
                    printf("future %2d finishing.                 Concurrent futures: %d\n", i, --concurrent);
                    atom.store(false);
                }
            ));
        }

        for (auto i = futures.rbegin(), end = futures.rend(); i != end; ++i) {
            i->get();
        }
    }
}

C:\Temp>cl /EHsc /nologo /W4 /MT /O2 /GL meow.cpp
meow.cpp
Generating code
Finished generating code

C:\Temp>meow
-----
launch::async | launch::deferred
future 0 starting (on thread 4468). Concurrent futures: 1
future 1 starting (on thread 4892). Concurrent futures: 2
future 2 starting (on thread 3252). Concurrent futures: 3
future 3 starting (on thread 1884). Concurrent futures: 4
future 4 starting (on thread 6548). Concurrent futures: 5
future 5 starting (on thread 4360). Concurrent futures: 6
future 7 starting (on thread 5056). Concurrent futures: 7
future 6 starting (on thread 7392). Concurrent futures: 8
future 49 starting (on MAIN thread). Concurrent futures: 9
future 0 finishing.                 Concurrent futures: 8
future 8 starting (on thread 4468). Concurrent futures: 9
future 6 finishing.                 Concurrent futures: 8
future 9 starting (on thread 7392). Concurrent futures: 9
future 49 finishing.                 Concurrent futures: 8
future 3 finishing.                 Concurrent futures: 7
future 48 starting (on MAIN thread). Concurrent futures: 8
future 10 starting (on thread 1884). Concurrent futures: 9
future 5 finishing.                 Concurrent futures: 8
future 11 starting (on thread 4360). Concurrent futures: 9
future 1 finishing.                 Concurrent futures: 8
future 2 finishing.                 Concurrent futures: 7
future 12 starting (on thread 4892). Concurrent futures: 8
future 7 finishing.                 Concurrent futures: 7
future 13 starting (on thread 3252). Concurrent futures: 8
future 14 starting (on thread 5056). Concurrent futures: 9
future 4 finishing.                 Concurrent futures: 8
future 15 starting (on thread 6548). Concurrent futures: 9
future 8 finishing.                 Concurrent futures: 8
future 16 starting (on thread 4468). Concurrent futures: 9
future 9 finishing.                 Concurrent futures: 8
future 17 starting (on thread 7392). Concurrent futures: 9
future 48 finishing.                 Concurrent futures: 8
future 47 starting (on MAIN thread). Concurrent futures: 9
future 11 finishing.                 Concurrent futures: 8
future 18 starting (on thread 4360). Concurrent futures: 9
future 10 finishing.                 Concurrent futures: 8
future 19 starting (on thread 1884). Concurrent futures: 9
future 13 finishing.                 Concurrent futures: 8
future 20 starting (on thread 3252). Concurrent futures: 9
future 12 finishing.                 Concurrent futures: 8
future 21 starting (on thread 4892). Concurrent futures: 9
future 15 finishing.                 Concurrent futures: 8
future 22 starting (on thread 6548). Concurrent futures: 9
future 14 finishing.                 Concurrent futures: 8
future 23 starting (on thread 5056). Concurrent futures: 9
future 16 finishing.                 Concurrent futures: 8
future 24 starting (on thread 4468). Concurrent futures: 9
future 17 finishing.                 Concurrent futures: 8
future 25 starting (on thread 7392). Concurrent futures: 9
future 18 finishing.                 Concurrent futures: 8
future 26 starting (on thread 4360). Concurrent futures: 9
future 21 finishing.                 Concurrent futures: 8
future 27 starting (on thread 4892). Concurrent futures: 9
future 20 finishing.                 Concurrent futures: 8
future 28 starting (on thread 3252). Concurrent futures: 9
future 47 finishing.                 Concurrent futures: 8
future 46 starting (on MAIN thread). Concurrent futures: 9
future 19 finishing.                 Concurrent futures: 8
future 29 starting (on thread 1884). Concurrent futures: 9
future 23 finishing.                 Concurrent futures: 8
future 30 starting (on thread 5056). Concurrent futures: 9
future 22 finishing.                 Concurrent futures: 8
future 31 starting (on thread 6548). Concurrent futures: 9
future 24 finishing.                 Concurrent futures: 8
future 32 starting (on thread 4468). Concurrent futures: 9
future 25 finishing.                 Concurrent futures: 8
future 33 starting (on thread 7392). Concurrent futures: 9
future 27 finishing.                 Concurrent futures: 8
future 34 starting (on thread 4892). Concurrent futures: 9
future 29 finishing.                 Concurrent futures: 8
future 35 starting (on thread 1884). Concurrent futures: 9
future 28 finishing.                 Concurrent futures: 8
future 36 starting (on thread 3252). Concurrent futures: 9
future 46 finishing.                 Concurrent futures: 8
future 45 starting (on MAIN thread). Concurrent futures: 9
future 30 finishing.                 Concurrent futures: 8
future 37 starting (on thread 5056). Concurrent futures: 9
future 26 finishing.                 Concurrent futures: 8
future 38 starting (on thread 4360). Concurrent futures: 9
future 32 finishing.                 Concurrent futures: 8
future 39 starting (on thread 4468). Concurrent futures: 9
future 31 finishing.                 Concurrent futures: 8
future 40 starting (on thread 6548). Concurrent futures: 9
future 34 finishing.                 Concurrent futures: 8
future 41 starting (on thread 4892). Concurrent futures: 9
future 35 finishing.                 Concurrent futures: 8
future 42 starting (on thread 1884). Concurrent futures: 9
future 33 finishing.                 Concurrent futures: 8
future 43 starting (on thread 7392). Concurrent futures: 9
future 36 finishing.                 Concurrent futures: 8
future 44 starting (on thread 3252). Concurrent futures: 9
future 37 finishing.                 Concurrent futures: 8
future 45 finishing.                 Concurrent futures: 7
future 38 finishing.                 Concurrent futures: 6
future 39 finishing.                 Concurrent futures: 5
future 40 finishing.                 Concurrent futures: 4
future 41 finishing.                 Concurrent futures: 3
future 42 finishing.                 Concurrent futures: 2
future 43 finishing.                 Concurrent futures: 1
future 44 finishing.                 Concurrent futures: 0
-----
launch::async
future 0 starting (on thread 4468). Concurrent futures: 1
future 6 starting (on thread 4360). Concurrent futures: 2
future 1 starting (on thread 3252). Concurrent futures: 3
future 8 starting (on thread 3704). Concurrent futures: 4
future 5 starting (on thread 7392). Concurrent futures: 5
future 4 starting (on thread 1884). Concurrent futures: 6
future 16 starting (on thread 7520). Concurrent futures: 7
future 17 starting (on thread 2732). Concurrent futures: 8
future 11 starting (on thread 4292). Concurrent futures: 9
future 18 starting (on thread 8816). Concurrent futures: 10
future 22 starting (on thread 6128). Concurrent futures: 11
future 23 starting (on thread 5148). Concurrent futures: 12
future 14 starting (on thread 6516). Concurrent futures: 13
future 7 starting (on thread 5056). Concurrent futures: 14
future 27 starting (on thread 6656). Concurrent futures: 15
future 25 starting (on thread 6956). Concurrent futures: 16
future 19 starting (on thread 6356). Concurrent futures: 17
future 30 starting (on thread 6764). Concurrent futures: 18
future 29 starting (on thread 4308). Concurrent futures: 19
future 28 starting (on thread 8200). Concurrent futures: 20
future 31 starting (on thread 8808). Concurrent futures: 21
future 20 starting (on thread 6772). Concurrent futures: 22
future 24 starting (on thread 7644). Concurrent futures: 23
future 21 starting (on thread 2304). Concurrent futures: 24
future 33 starting (on thread 7452). Concurrent futures: 25
future 34 starting (on thread 8688). Concurrent futures: 26
future 2 starting (on thread 4892). Concurrent futures: 27
future 26 starting (on thread 8320). Concurrent futures: 28
future 32 starting (on thread 1824). Concurrent futures: 29
future 10 starting (on thread 1692). Concurrent futures: 30
future 37 starting (on thread 5740). Concurrent futures: 31
future 36 starting (on thread 388). Concurrent futures: 32
future 38 starting (on thread 5792). Concurrent futures: 33
future 39 starting (on thread 4028). Concurrent futures: 34
future 9 starting (on thread 8252). Concurrent futures: 35
future 40 starting (on thread 6156). Concurrent futures: 36
future 13 starting (on thread 1708). Concurrent futures: 37
future 3 starting (on thread 6548). Concurrent futures: 38
future 42 starting (on thread 5036). Concurrent futures: 39
future 41 starting (on thread 7720). Concurrent futures: 40
future 43 starting (on thread 9036). Concurrent futures: 41
future 45 starting (on thread 8348). Concurrent futures: 42
future 44 starting (on thread 2148). Concurrent futures: 43
future 35 starting (on thread 7576). Concurrent futures: 44
future 12 starting (on thread 9168). Concurrent futures: 45
future 47 starting (on thread 8280). Concurrent futures: 46
future 15 starting (on thread 1264). Concurrent futures: 47
future 46 starting (on thread 7376). Concurrent futures: 48
future 49 starting (on thread 8344). Concurrent futures: 49
future 48 starting (on thread 5300). Concurrent futures: 50
future 6 finishing.                 Concurrent futures: 49
future 27 finishing.                 Concurrent futures: 48
future 21 finishing.                 Concurrent futures: 47
future 18 finishing.                 Concurrent futures: 46
future 19 finishing.                 Concurrent futures: 45
future 1 finishing.                 Concurrent futures: 44
future 17 finishing.                 Concurrent futures: 43
future 42 finishing.                 Concurrent futures: 42
future 4 finishing.                 Concurrent futures: 41
future 11 finishing.                 Concurrent futures: 40
future 40 finishing.                 Concurrent futures: 39
future 38 finishing.                 Concurrent futures: 38
future 5 finishing.                 Concurrent futures: 37
future 43 finishing.                 Concurrent futures: 36
future 13 finishing.                 Concurrent futures: 35
future 37 finishing.                 Concurrent futures: 34
future 12 finishing.                 Concurrent futures: 33
future 28 finishing.                 Concurrent futures: 32
future 49 finishing.                 Concurrent futures: 31
future 20 finishing.                 Concurrent futures: 30
future 24 finishing.                 Concurrent futures: 29
future 9 finishing.                 Concurrent futures: 28
future 8 finishing.                 Concurrent futures: 27
future 35 finishing.                 Concurrent futures: 26
future 36 finishing.                 Concurrent futures: 25
future 46 finishing.                 Concurrent futures: 24
future 47 finishing.                 Concurrent futures: 23
future 0 finishing.                 Concurrent futures: 22
future 10 finishing.                 Concurrent futures: 21
future 45 finishing.                 Concurrent futures: 20
future 16 finishing.                 Concurrent futures: 19
future 31 finishing.                 Concurrent futures: 18
future 30 finishing.                 Concurrent futures: 17
future 23 finishing.                 Concurrent futures: 16
future 7 finishing.                 Concurrent futures: 15
future 26 finishing.                 Concurrent futures: 14
future 3 finishing.                 Concurrent futures: 13
future 33 finishing.                 Concurrent futures: 12
future 32 finishing.                 Concurrent futures: 11
future 29 finishing.                 Concurrent futures: 10
future 22 finishing.                 Concurrent futures: 9
future 14 finishing.                 Concurrent futures: 8
future 25 finishing.                 Concurrent futures: 7
future 15 finishing.                 Concurrent futures: 6
future 34 finishing.                 Concurrent futures: 5
future 2 finishing.                 Concurrent futures: 4
future 39 finishing.                 Concurrent futures: 3
future 41 finishing.                 Concurrent futures: 2
future 44 finishing.                 Concurrent futures: 1
future 48 finishing.                 Concurrent futures: 0
-----
launch::deferred
future 49 starting (on MAIN thread). Concurrent futures: 1
future 49 finishing.                 Concurrent futures: 0
future 48 starting (on MAIN thread). Concurrent futures: 1
future 48 finishing.                 Concurrent futures: 0
future 47 starting (on MAIN thread). Concurrent futures: 1
future 47 finishing.                 Concurrent futures: 0
future 46 starting (on MAIN thread). Concurrent futures: 1
future 46 finishing.                 Concurrent futures: 0
future 45 starting (on MAIN thread). Concurrent futures: 1
future 45 finishing.                 Concurrent futures: 0
future 44 starting (on MAIN thread). Concurrent futures: 1
future 44 finishing.                 Concurrent futures: 0
future 43 starting (on MAIN thread). Concurrent futures: 1
future 43 finishing.                 Concurrent futures: 0
future 42 starting (on MAIN thread). Concurrent futures: 1
future 42 finishing.                 Concurrent futures: 0
future 41 starting (on MAIN thread). Concurrent futures: 1
future 41 finishing.                 Concurrent futures: 0
future 40 starting (on MAIN thread). Concurrent futures: 1
future 40 finishing.                 Concurrent futures: 0
future 39 starting (on MAIN thread). Concurrent futures: 1
future 39 finishing.                 Concurrent futures: 0
future 38 starting (on MAIN thread). Concurrent futures: 1
future 38 finishing.                 Concurrent futures: 0
future 37 starting (on MAIN thread). Concurrent futures: 1
future 37 finishing.                 Concurrent futures: 0
future 36 starting (on MAIN thread). Concurrent futures: 1
future 36 finishing.                 Concurrent futures: 0
future 35 starting (on MAIN thread). Concurrent futures: 1
future 35 finishing.                 Concurrent futures: 0
future 34 starting (on MAIN thread). Concurrent futures: 1
future 34 finishing.                 Concurrent futures: 0
future 33 starting (on MAIN thread). Concurrent futures: 1
future 33 finishing.                 Concurrent futures: 0
future 32 starting (on MAIN thread). Concurrent futures: 1
future 32 finishing.                 Concurrent futures: 0
future 31 starting (on MAIN thread). Concurrent futures: 1
future 31 finishing.                 Concurrent futures: 0
future 30 starting (on MAIN thread). Concurrent futures: 1
future 30 finishing.                 Concurrent futures: 0
future 29 starting (on MAIN thread). Concurrent futures: 1
future 29 finishing.                 Concurrent futures: 0
future 28 starting (on MAIN thread). Concurrent futures: 1
future 28 finishing.                 Concurrent futures: 0
future 27 starting (on MAIN thread). Concurrent futures: 1
future 27 finishing.                 Concurrent futures: 0
future 26 starting (on MAIN thread). Concurrent futures: 1
future 26 finishing.                 Concurrent futures: 0
future 25 starting (on MAIN thread). Concurrent futures: 1
future 25 finishing.                 Concurrent futures: 0
future 24 starting (on MAIN thread). Concurrent futures: 1
future 24 finishing.                 Concurrent futures: 0
future 23 starting (on MAIN thread). Concurrent futures: 1
future 23 finishing.                 Concurrent futures: 0
future 22 starting (on MAIN thread). Concurrent futures: 1
future 22 finishing.                 Concurrent futures: 0
future 21 starting (on MAIN thread). Concurrent futures: 1
future 21 finishing.                 Concurrent futures: 0
future 20 starting (on MAIN thread). Concurrent futures: 1
future 20 finishing.                 Concurrent futures: 0
future 19 starting (on MAIN thread). Concurrent futures: 1
future 19 finishing.                 Concurrent futures: 0
future 18 starting (on MAIN thread). Concurrent futures: 1
future 18 finishing.                 Concurrent futures: 0
future 17 starting (on MAIN thread). Concurrent futures: 1
future 17 finishing.                 Concurrent futures: 0
future 16 starting (on MAIN thread). Concurrent futures: 1
future 16 finishing.                 Concurrent futures: 0
future 15 starting (on MAIN thread). Concurrent futures: 1
future 15 finishing.                 Concurrent futures: 0
future 14 starting (on MAIN thread). Concurrent futures: 1
future 14 finishing.                 Concurrent futures: 0
future 13 starting (on MAIN thread). Concurrent futures: 1
future 13 finishing.                 Concurrent futures: 0
future 12 starting (on MAIN thread). Concurrent futures: 1
future 12 finishing.                 Concurrent futures: 0
future 11 starting (on MAIN thread). Concurrent futures: 1
future 11 finishing.                 Concurrent futures: 0
future 10 starting (on MAIN thread). Concurrent futures: 1
future 10 finishing.                 Concurrent futures: 0
future 9 starting (on MAIN thread). Concurrent futures: 1
future 9 finishing.                 Concurrent futures: 0
future 8 starting (on MAIN thread). Concurrent futures: 1
future 8 finishing.                 Concurrent futures: 0
future 7 starting (on MAIN thread). Concurrent futures: 1
future 7 finishing.                 Concurrent futures: 0
future 6 starting (on MAIN thread). Concurrent futures: 1
future 6 finishing.                 Concurrent futures: 0
future 5 starting (on MAIN thread). Concurrent futures: 1
future 5 finishing.                 Concurrent futures: 0
future 4 starting (on MAIN thread). Concurrent futures: 1
future 4 finishing.                 Concurrent futures: 0
future 3 starting (on MAIN thread). Concurrent futures: 1
future 3 finishing.                 Concurrent futures: 0
future 2 starting (on MAIN thread). Concurrent futures: 1
future 2 finishing.                 Concurrent futures: 0
future 1 starting (on MAIN thread). Concurrent futures: 1
future 1 finishing.                 Concurrent futures: 0
future 0 starting (on MAIN thread). Concurrent futures: 1
future 0 finishing.                 Concurrent futures: 0

With this fix, launch::async doesn't use std::thread. (If you want std::thread, you know where to find it.) It uses VC's Concurrency Runtime, but differently than launch::async | launch::deferred. The differences are:

launch::async | launch::deferred may or may not run on a different thread, and ConcRT will avoid spinning up more threads than is necessary to saturate the hardware.

launch::async will run on a different thread, and ConcRT is willing to spin up many more threads than the hardware has logical cores for. Unlike std::thread, ConcRT will reuse threads if possible, for greater efficiency.

We believe that this conforms to the Standard, and results in desirable behavior for the vast majority of users (including your example).

(Also, I have intentionally used the world's dumbest atomic spinlock in my example. Using std::mutex to guard the output would allow ConcRT to schedule additional work, which would influence the output!)

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Petke Himself on 4/15/2012 at 8:45 AM
I made a new toy example that shows better what is going on. Turns out the threads themselves are reused, and not only scheduled inefficiently. http://pastebin.com/5dWCjjNY

Posted by Petke Himself on 4/13/2012 at 11:58 PM
As this bug is important to me; I took the time to make a toy example that shows the problem. This bug or behaviour makes std::async all but useless to me, and I expect others will find the same problem. I would be very grateful if someone could take a look at this. Thanks /Patrik

#include <vector>
#include <iostream>
#include <future>
#include <thread>

#include <boost/timer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

struct Trace {
    Trace(int id) : id_(id) {
        std::cout << " begin " << id_ << std::endl;
    }
    ~Trace() {
        std::cout << " end " << id_ << std::endl;
    }

    int id_;
};

int dummyExpensiveBlockingNetworkCall(int id) {
    Trace trace(id);

    int result = 0;
    
    boost::timer    tm;

    while(tm.elapsed() < 10.0) {
        ++result; //busy wait
    }

    return result;
}

void slow() {
    std::vector<std::future<int>> futures;
    for (int i = 0; i < 10; ++i)
    {
        auto fut = std::async(std::launch::async, [=]()
        {
            return dummyExpensiveBlockingNetworkCall(i);
        });
        futures.push_back(std::move(fut));
    }

    std::vector<int> resVec;
    std::for_each(futures.begin(), futures.end(), [&](std::future<int> & fut)
    {
        resVec.push_back(fut.get());
    });

    /*
    std::for_each(resVec.begin(), resVec.end(), [](int result) {
        std::cout << result << ", ";
    });
    */

}

void fast() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i)
    {
        auto th = std::thread([=]()
        {
            dummyExpensiveBlockingNetworkCall(i);
        });
        threads.push_back(std::move(th));
    }

    std::vector<int> resVec;
    std::for_each(threads.begin(), threads.end(), [&](std::thread& th)
    {
        th.join();
    });
}

int main()
{
    slow(); //takes up to 100 seconds as some work does not start before others have finsihed. As in the work is not paralell even thoough we told it to use std::launch::async.
    /*
    output:
         begin 0
         begin 1
         begin 2
         end 0
         end end 1
         begin 3
        2
         begin 4
         end 3
         end 4
         begin 5
         begin 7
         begin 6
         end 7
         begin 8
         end 6
         end 5
         begin 9
         end 8
         end 9    
    */

    //fast(); //takes at most 10 seconds as all begin come before end. Work is truly parallell
    /*
        output:
         begin 0
         begin 1
         begin 2
         begin 3
         begin 4
         begin 5
         begin 6 begin 8
         begin 7

         begin 9
         end 0 end 2
         end 5
         end 1
         end 3
         end 4

         end end 7
         end 6
        8
         end 9    
*/

}

Posted by MS-Moderator09 [Feedback Moderator] on 4/9/2012 at 7:07 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by MS-Moderator01 on 4/5/2012 at 11:50 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.