【问题标题】:C++ REST SDK: asynchronous tasks vs. C++11 multithreadingC++ REST SDK:异步任务与 C++11 多线程
【发布时间】:2016-07-20 04:19:31
【问题描述】:

这是一个关于 C++ REST SDK 的异步任务特性的概念性问题(也许也是一个菜鸟问题)。

在一个基本应用程序中,我有一个客户端并执行多个请求,例如喜欢

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*/});
}

(for-loop只是为了表明请求经常发送,我的代码中并没有真正使用它)。

问题:

  • 据我了解,异步任务库然后以并行方式处理这些传入请求——这意味着不是主线程以类似事件的方式处理所有任务,而是库将任务分配给以某种(--对我来说是不透明的--)方式的底层线程池。我没听错吗?

  • 如果前面的观点是正确的,那么是否有任何理由将 REST SDK 与 C++ 的多线程功能结合起来。例如,再次采用上述循环,启动 10 个线程,并在每个进程中进行 10 次循环迭代。这有意义还是没有必要?

  • 此外,一般来说,是否存在应该通过 C++11 多线程特性结合 ppl 功能的常见模式?或者,依靠 REST SDK 和 ppl 来更好地完成工作是否安全?

(信息:我也在cpprest discussion page上问过这个问题。但是,这个论坛似乎不再维护了。)

【问题讨论】:

    标签: c++ multithreading c++11 ppl casablanca


    【解决方案1】:

    据我所知,异步任务库会处理这些 以并行方式传入的请求——这意味着不是主要的 线程以类似事件的方式处理所有任务,而不是 库在某些(--to)中将任务分配给底层线程池 我不透明--)方式。我猜对了吗?

    是的,在 REST SDK 中,它们使用线程池来启动任务延续。在 Windows 上,它们使用 Windows API ThreadPool 函数(CreateThreadPoolTrySubmitThreadpoolCallback 等)。在 Linux 上,他们使用 Boost 版本。

    如果前面的观点是正确的,那么还有什么理由将 REST SDK 与 C++ 的多线程功能结合起来。为了 例如,再次使用上述循环,启动 10 个线程,并在每个线程中 处理 10 次循环迭代。这有意义吗? 没必要?

    完全没有必要,平台有自己的线程池。

    此外,一般来说,是否有任何常见的模式? 通过 C++11 多线程功能结合 ppl 功能?要么 依靠 REST SDK 和 ppl 在后台获得 工作做得更好?

    嗯,task 的整个想法是抽象出线程的使用。在处理许多并行任务时,线程不能很好地扩展。传统的方法是使用线程池,不为每个新任务生成一个新线程。

    ppl 任务使您能够以更优雅的方式处理异步 IO。您将 CPU 绑定任务封装在 ppl::task 中,在这些任务中,您可以生成另一个异步 IO 操作,并在异步 IO 完成后使用 ppl::task::then 继续执行 CPU 绑定任务。

    该机制是task-&gt; aync IO -&gt; continuation task-&gt; async IO -&gt;task 等的一个链。当任务启动 IO 操作时,底层线程池将继续执行下一个任务。当异步 IO 完成时,它将继续任务排入线程池任务队列的末尾。

    所以不,你不应该直接自己创建任何std::thread。但是,您确实想要使用同步对象,例如 std::mutex if 您的任务访问任何线程资源。

    ------------------------------------
    一个很好的奖励:
    在带有visual studio 2015 RTM及更高版本的VC++上,你可以在任务上使用await并摆脱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
    }
    

    ----------------------------------- ----
    一个不好的好处:
    根据我使用 REST SDK 的经验,它的性能极差,这不是您对 C++ 平台的期望。

    【讨论】:

    • 好答案,谢谢!还有两个问题:(i)负载平衡呢?假设一个请求有很大的响应,而 99 有一个小的响应。 ppl能正确处理这个吗? (ii) 跟进:如果我在不同的 std::threads 中使用异步任务,每个线程都会有自己的线程池,不是吗? ...因此可以用来实现自定义平衡?
    • (i) 有点像。它取决于底层的线程池实现。 (ii) 不,平台总是只有一个线程池
    • 这是否意味着无法进行自定义负载平衡?
    • 另一个问题:您正在写的是在访问共享资源时使用std::mutex 或其他同步对象是合理的。这与“普通”多线程(即基于std::thread)中的工作方式完全一样吗?或者还有什么需要考虑的?
    • 很高兴知道。你有这方面的参考吗? -- 因为我在网上搜索了一整天,几乎找不到关于卡萨布兰卡锁的任何信息。
    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 2018-03-08
    • 2010-12-18
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多