谈谈Boost网络编程(3)—— 一些坑

很多时候,我们以为采用了一种新技术(尤其是成熟的技术),过程应该是一马平川的。然而实际上,采用新技术的过程却是掉入了各种坑里。究其原因,或者是使用方式有问题,或者是效率的白白浪费。这一章,我想讲讲,我在使用Boost Asio进程网络编程时,所遇到的各种坑。

其一、CPU占用100%问题。

在没有采用异步编程之前,程序占用100%基本是不敢想象的事情,因为一旦程序占用100%的CPU,那必然是代码中出现了死循环的BUG。但是采用了Boost Asio后,我发现新系统很容易就跑满了CPU。Why?

1)服务端接收任务过快。快一直是我们系统所追求的,为此我们特别进行了优化,支持一次接收一组任务(100-300之间)。然而我们处理任务时,client一次最多只能够处理10条任务,这就是典型的生产者-消费者问题。生产者能力大于消费者,而且消费者在消化时(HTTP发送任务时),对方反馈是同步反馈的,这就造成了CPU的持续增加。再则,任务完毕被发送到report_runner时,反馈任务是一条一条反馈,这又是生产能力大于了消费能力。

针对此问题,我们做了一些限制和优化:stream_server增加限速功能,report_client可以合并反馈。

2)bind意味着拷贝,尽量在bind时传递指针而不是实例。

其二、shared_ptr和多态。

如果我有一个基类的shared_ptr,我可以用它来指向具体的子类吗?答案是需要将子类的shared_ptr赋值于这个指针,否则无法实现多态。

其三、子进程问题。

由于我们的客户端只运行于linux,所以这里只描述在基于boost asio的多线程程序中如何再做到多进程。注意:这里有一个前提,子进程中只调用shell或可执行,并不用到父进程中的asio实例。

为什么要单独讲子进程问题呢?因为Boost的asio并不是fork安全的,而且其Doc中特别指出了在子进程中需要调用notify_event来通知asio以使fork安全。这至少造成了我的疑惑:如果我不需要在子进程中使用Asio,我还需要notify吗?答案是不需要。正如我们系统所遇到的,只需要调用linux的exec*即可。

进一步,由于我们并不需要拷贝父进程,所以用vfork取代了fork。

时间: 2024-11-10 17:29:26

谈谈Boost网络编程(3)—— 一些坑的相关文章

谈谈Boost网络编程(1)——旧系统的问题

前段时间一气呵成,把公司的陈旧代码完全替换掉了.这其间主要用到了Boost Asio,以及其他Boost库的组件(thread,bind等).这次开发,让我收获颇多. 首先,是技术上的成长.刚入公司时,负责维护的是很陈旧的代码,不过由于当时自己的视野局限,并没有认为其到底有多陈旧.后期随着技术的成长,以及视野的开阔,便有了重构系统的决定.既然说到陈旧,那么这里就简单说一下旧系统的旧在何处: 1)多线程多连接的服务端. 2)多线程多连接的客户端.第1)点和第2)点的缺点是显而易见的,线程和连接绑定

谈谈Boost网络编程(2)—— 新系统的设计

写文章之前.我们一般会想要採用何种方式,是"开门见山",还是"疑问式开头".写代码也有些类似.在编码之前我们须要考虑系统总体方案,这也就是各种设计文档的作用.在设计新系统之初,我基本的目的是:保证高效率:保证高扩展性. 效率评价以"任务数/秒"做单位. 因为我的系统仅仅是client,不应该占用太多内存以及CPU.所以内存占用率,CPU使用率也被作为一个硬性指标.那么这里就存在疑问的地方:client有必要採用Boost Asio来做吗?我个人认

Boost.Asio c++ 网络编程翻译(26)

Boost.Asio-其他特性 这章我们讲了解一些Boost.Asio不那么为人所知的特性.标准的stream和streambuf对象有时候会更难用一些,但正如你所见.它们也有它们的益处.最后,你会看到姗姗来迟的Boost.Asio协程的入口,它能够让你的异步代码变的很易读.这是很惊人的一个特性. 标准stream和标准I/O buffer 读这一章节之前你须要对STL stream和STL streambuf对象有所了解. Boost.Asio在处理I/O操作时支持两种类型的buffer: b

Boost.Asio c++ 网络编程翻译(6)

io_service类 你应该已经发现大部分使用Boost.Asio编写的代码都会使用几个ios_service的实例.ios_service是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用完成处理程序. 如果你选择用同步的方式来创建你的应用,你不需要考虑我将在这一节向你展示的东西. 你可以用几种不同的方式来使用io_service.在下面的例子中,我们有3个异步操作,2个socket连接和一个计时器等待: 有一个io_service和一个处理线程

Boost Asio 网络编程 基本用法

Boost Asio 网络编程 基本用法 flyfish 2015-2-9 IP地址 boost::asio::ip::address表示IP地址,同时支持ipv4和ipv6. boost::asio::ip::address addr; addr = addr.from_string("127.0.0.1"); assert(addr.is_v4()); OutputDebugStringA(addr.to_string().c_str()); addr = addr.from_st

Boost.Asio c++ 网络编程翻译(30)[完结]

PS:至此终于完成了Boost.Asio C++ network programming一书的翻译,这是我人生第一本完整翻译的书,从开始的磕磕绊绊,到最后小有心得,我收获很多.我将把这个系列的博客进行整理和校对,希望有兴趣的人可以帮我一起,来给大家提供更好更专业的阅读体验. 句柄追踪信息到文件 默认情况下,句柄的追踪信息被输出到标准错误流(相当于std::cerr).你想把输出重定向到其他地方的可能性是非常高的.对于控制台应用,输出和错误输出都被默认输出到相同的地方,也就是控制台.但是对于一个w

Boost.Asio c++ 网络编程翻译(1)

第一次翻译,希望大家多多指正 实战出精华 Boost.Asio C++ 网络编程 用具体的C++网络编程例子来提升你的技能 John Torjan 用具体的C++网络编程例子来提升你的技能 Copyright ? 2013 Packt Publishing 版权所有,除了在鉴定文章或者评论中进行简单引用,如果没有经过出版者事先的书面授权,该书的任何部分都不能被转载.存储在检索系统中.或者以任何形式和方式传阅. 在这本书准备发行之前,我们已经尽我们最大的努力去保证书中信息的准确性.但是,这本书中包

boost Asio网络编程简介

.markdown-preview:not([data-use-github-style]) { padding: 2em; font-size: 1.2em; color: rgb(171, 178, 191); background-color: rgb(40, 44, 52); overflow: auto } .markdown-preview:not([data-use-github-style])>:first-child { margin-top: 0px } .markdown-

网络编程中的关键问题总结

总结下网络编程中关键的细节问题,包含连接建立.连接断开.消息到达.发送消息等等: 连接建立 包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接. accept接受连接的问题在本文最后会聊到,这里谈谈connect的关键点:     使用非阻塞连接建立需要注意:     connect/select返回后,可能没有连接上:需要再次确认是否成功连接: 步骤为: 使用异步connect直接连接一次,因为使用了非阻塞,函数立刻返回: 检查返回值,为0成功连接,否则加入到s