Muduo网络库实战(二):实现服务器与客户端的连接
1. 方案的确定
1)基本需求
用户1000+, IO压力不大;
多个客户端打开网站,输入查询字符串strclient,发送给服务器=》服务器接收客户端发过来的数据并处理,将结果返回给客户端;
2)并发网络服务程序设计方案
详见:《Muduo_网络库使用手册》的1.6节-《详解Muduo多线程模型》
@ muduo中TcpServer模式的选择:多线程模式
模式一:单线程,accept与TcpConnection用同一个线程做IO;
模式二:多线程,accept与EventLoop在同一个线程,另外创建一个EventThreadPool,新到的链接会被round-robin方式分配到线程池中;
=》问题
单线程和多线程运行时候的区别?
=》分析:采用多线程而不是多进程的原因
鉴于dealdata(假设服务器处理客户端数据的函数为dealdata)是一个计算密集型的任务,其瓶颈在CPU。为了让单线程程序充分利用CPU资源,简单的方法是在同一台机器上部署多个dealdata进程,让每个进程占用不同的端口。这样就把难题推给了客户端,因为客户端需要自己做负载均衡,然而鉴于本项目的用户较少(约1000),服务器进程不需要开很多,所以部署复杂均衡似乎小题大做;
@ 并发网路服务程序的选择:方案8
=》分析
方案6:在收到客户端的请求后,不在reactor线程计算,而是创建一个新线程去计算,以充分利用多核CPU。这个方案的特点是out-of-order,即同时创建多个线程去计算同一个连接上收到的多个请求,那么算出的结果的次序是不确定的;(这不满足本项目的需求)
方案8:为弥补方案6中每个请求创建线程的缺陷,根据用户的多少,使用固定大小的线程池。全部的IO工作都在一个reactor线程完成,而计算任务交给threadpool;因为计算任务彼此独立,而且IO的压力不大,这种方案很适用;
=》问题
公司用户1000人,如果1000人同时连接,muduo库的压力测试怎样?算不算IO压力不大的情形;
2.实战
muduo库是使用基于对象实现的,经常会使用到bind、function等函数实现函数回调机制;
根据《Muduo网络库使用手册》中的“数独求解服务器”和“Boost.Asio的聊天服务器”,结合muduo源文件中example下的代码写出父服务器与客户端交互操作的多线程服务器程序。
@ muduo::string 与 std::string的转换
1 // muduo->std 2 muduo::string muduostr = "..."; 3 std::string str(muduostr.c_str(), muduostr.size()); 4 // std->muduo 5 std::string str = "..."; 6 muduo::string muduostr(str.c_str(), str.size());
@ muduo中使用threadpool时出现的问题
参考资料:使用muduo编译链接错误 undefined reference to `muduo::ThreadPool::run(boost::function<void ()()>&&)'
出现上述错误是因为使用的muduo库为-lmuduo_base,但是此链接库中并没有muduo::ThreadPool;
应该在Makefile中将-lmuduo_base更改为-lmuduo_base_cpp11。