Search code examples
c++multithreadingc++11pplcasablanca

C++ REST SDK: asynchronous tasks vs. C++11 multithreading


This is a conceptual question on the asynchronous task feature of the C++ REST SDK (and maybe also a bit of a noob question).

In a basic application, I have a client and perform several requests, e.g. like

http_client client(U("whatever"));

for(int i=0; i<100; ++i)
{
    http_request request;
    //fill the request
    client.request(request).then([](http_response response) { /* do something*/});
}

(The foor-loop is just to indicate that the request is sent often, I don't really use it in my code).

Questions:

  • As far I understand, the asynchronous task library then handles those incoming requests in a parallel way -- meaning that not the main thread handles all tasks in an event-like fashion, but rather the library assigns the tasks to an underlying thread pool in some (--to me intransparent--) way. Did I get that correct?

  • If the previous view is correct, then is there any reason to combine the REST SDK with the multithreading capabilities of C++. For example, taking again the above loop, start 10 threads and in each one process 10 loop iterations. Does this makes sense or is it unnecessary?

  • Moreover, in general, are there any common patterns where one should combine the ppl-capabilities by the C++11 multithreading feature? Or is it safe to rely that the REST SDK and ppl under the hood get the job done better?

(Info: I've asked this question also on the cpprest discussion page. However, this forum seems to be not maintained anymore.)


Solution

  • As far I understand, the asynchronous task library then handles those incoming requests in a parallel way -- meaning that not the main thread handles all tasks in an event-like fashion, but rather the library assigns the tasks to an underlying thread pool in some (--to me intransparent--) way. Did I get that correct?

    Yes, in the REST SDK, they use a threadpool to launch the task continuation. on windows, they use the Windows API ThreadPool functions (CreateThreadPool, TrySubmitThreadpoolCallback etc.) . on Linux, they use the Boost one.

    If the previous view is correct, then is there any reason to combine the REST SDK with the multithreading capabilities of C++. For example, taking again the above loop, start 10 threads and in each one process 10 loop iterations. Does this makes sense or is it unnecessary?

    Completly unnecessery, the platform has its own thread pool.

    Moreover, in general, are there any common patterns where one should combine the ppl-capabilities by the C++11 multithreading feature? Or is it safe to rely that the REST SDK and ppl under the hood get the job done better?

    well, the whole idea of a task is to abstract away the use of threads. threads don't scale well when dealling with many parallel tasks. the conventional approach is to use a thread pool to not spawn a new thread for each new task.

    ppl tasks gives you the possibility to handle asynchronous IO in more elegant way. you encapsulate the CPU bound tasks in ppl::task, in these tasks, you can spawn another async IO operations, and use ppl::task::then to continue doing CPU bound tasks when the async IO is finished.

    the mechanism is a chain of task-> aync IO -> continuation task-> async IO ->task and so one. when the task launches an IO operation, the underlying thread pool moves on to the next task. when the async IO is finished, it queues the continuation task on the end of the thread pool tasks queue.

    So no, you should not directly create any std::thread on you own. you do however, want to use syncrhonization objects like std::mutex if you task accesses any shread resource.

    ------------------------------------
    A good bonus:
    on VC++ with visual studio 2015 RTM and above, you can use await on tasks and get rid of the then:

    http_client client(U("whatever"));
    
    for(int i=0; i<100; ++i)
    {
        http_request request;
        //fill the request
       auto response = await client.request(request);
       //do something with the response
    }
    

    ---------------------------------------------------
    A bad bonus:
    with my experience with REST SDK, its performance is extremly poor, not something you'd expect from a C++ platform.