TCP 服务器 w/ boost::asio,线程池与无堆栈协程的可扩展性
TCP Server w/ boost::asio, scalability of thread pool vs stackless coroutines
我正在构建一个基于 TCP 的守护进程,用于 HTTP 请求的预处理/后处理。 客户端将连接到Apache HTTPD(或IIS(,自定义Apache/IIS模块会将请求转发到我的TCP守护程序进行进一步处理。 我的守护程序需要向上扩展(但不能横向扩展(以处理大量流量,并且大多数请求都是小而短暂的。 守护程序将在C++中构建,并且必须是跨平台的。
我目前正在研究提升 asio 库,这似乎是天作之合。 但是,我很难理解无堆栈协程与线程池模式的优点。 具体来说,我在这里查看HTTP服务器示例#3和HTTP服务器示例#4:http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/examples.html
尽管我在谷歌上搜索了所有内容,但我无法完全理解无堆栈协程服务器的优点,以及它相对于多核系统上的线程池服务器的性能。
根据我的要求,两者中哪一个最合适,为什么? 请随意"简化"您对无堆栈协程想法的回答,我在这里仍然处于不稳定状态。 谢谢!
编辑:另一个随机的想法/讨论问题:Boost HTTP 服务器示例 #4 被描述为">使用无堆栈协程实现的单线程 HTTP 服务器"。 好的,所以它完全是单线程的(对吧? 即使在父进程"分叉"给孩子之后? 请参阅服务器.cpp在示例 #4(...单线程会成为多核系统的瓶颈吗? 我假设任何阻止操作都会阻止所有其他请求执行。 如果确实如此,为了最大限度地提高吞吐量,我正在考虑一个基于协程的接收数据异步事件,一个用于我的内部阻塞任务的线程池(利用多核(,然后是一个异步发送和关闭连接机制。 同样,可扩展性至关重要。 有什么想法吗?
我最近研究了boost.asio在多核机器上的可扩展性。到目前为止的主要结论是,它确实引入了开销,锁争用和其他上下文切换(至少在Linux上(,请参阅我关于这些主题的一些博客文章:
- http://cmeerw.org/blog/748.html#748
- http://cmeerw.org/blog/751.html#751
我还在asio邮件列表中启动了一个线程,以检查我没有错过任何明显的东西,请参阅 http://comments.gmane.org/gmane.comp.lib.boost.asio.user/5133
如果您主要关心的是性能和可扩展性,那么恐怕没有明确的答案 - 您可能需要进行一些原型设计并查看性能。
如果您有任何阻塞操作,那么您肯定希望使用多个线程 - 另一方面,上下文切换和锁争用会降低多个线程的性能(至少您必须非常小心(。
编辑:只是为了澄清无堆栈协程的东西:它本质上只是一些语法糖,使异步 API 看起来更像顺序/阻塞调用。
您需要测量效果以确定由于难以预测引用位置、CPU 指令缓存、调度延迟等的相对影响而实际发生的情况。
如果您想要启发式猜测,请考虑使用 n 个堆栈大小为 S 的线程,每个线程总是占用 nS 字节,无论每个线程实际使用的堆栈空间是多少。如果这会将您推到页面边界,则可能会显著降低性能。
- 将参数推送到调用堆栈 (C++) 的可移植方法
- 如何使用于 catch2 测试和项目运行的 cmake 目标更具可扩展性和合理性?
- 仅针对特定可执行文件增加堆栈大小
- 如何修复可视化工作室中的"C2061语法错误标识符"堆栈?
- 可视化 在C++中实现堆栈
- 如何在C++中实现可动态调整大小的堆栈
- 为什么异常总是在具有可破坏堆栈对象的非叶函数中产生开销
- 逆变类型和扩展性
- 计算C++堆栈需求;如何获得可读的交易品种表
- 是否可以为 CString 返回堆栈对象以及为什么 /GR 导致未定义的行为dynamic_cast
- 如何在 Linux 下为可执行文件分配堆栈
- 可视化泄漏检测器(VLD)显示空的调用堆栈
- 可用于激活堆栈的内存
- 可视化C++映射迭代和堆栈损坏
- TCP 服务器 w/ boost::asio,线程池与无堆栈协程的可扩展性
- 类似(图形可视化)堆栈跟踪(可视化调试)的树
- 使用 Python 插件可扩展性编写跨平台应用程序的最简单方法
- C++中可变长度堆栈上的可视化数组分配
- C标准库的可扩展性对C++程序的影响有多大
- Visual Studio 2013 中的 Lua C API 堆栈可视化工具/查看器