http://hi.baidu.com/netpet/blog/item/2cc79216d9012b54f2de32b9.html

前段时间将新的web模型办到linux上来,用epoll代替了IOCP,经测试确实性能提高了很多,吞吐量也寓所提高,对于linux下面的网络编程不是三言两语就能说得透的了,加上多线程就更麻烦了,但是epoll模型的精髓就是事件驱动,这种模型提供了保持连接socket直线增涨而性能不会直线下降的特性,纵观epoll kueuen select等等,所有都是在解决一个socket不需要一个线程的问题,将事件去分开来
    在ningx(有人用他同时保持了3万个处理连接)上的到了一些体会,这些不仅使用于web这样模型的server,同样适合于所有其他的比如游戏、ftp服务器等。
    维持高在线人数的关键问题在于事件处理模型需要m:n,m远<n, m为socket,n为连接socket,不管你有多少个cpu(比如2cpu 4核),计算机能同时处理的线程数都是很少的,socket的关键在于网络等IO的延迟,如果让线程堵塞在一个网络IO上那所有的基础优化算法都是白搭,因为算法的不佳只能影想很短的时间,但是网络IO延迟就很难讲了,有位前辈说了很好的一句话:做多服务器网络协作程序任何时候记住减少一次路由比优化100次一个算法都划算
   nginx的做法是将处理程序严格区分开来(本次我作的Flower web server也是基于此原理),等待epoll等事件通知,他在全局范围内维护了两个链表,一个读连表,一个写链表,epoll等系统网络通知通知了某个socket可操作后他便将状态保存在相应的变量里面,然后采取m个线程轮询执行任务,这样线程就不用等待网络io堵塞,正常的一个read socket数据需要循环,直到数据读完或者产生错误,但我的处理不是这样的,我在全局范围内维护一个统一的socket fd表,这是linux的特性决定的,因为linux的socket fd是从很小的值开始的,并且同一时间内不会重复(估计内部有线程锁),所有fd本身就是一个重要的标识量,并且一个大的fd释放后还会从小的开始重复利用,winsows下的就不一样,他是一个长长的指针,所有我的全局状态表就需要一个用fd作为索引的标识就可以了,最大的fd也就是同时保持在线人数的大体数字,我设置了一个20000的状态表,暂用栈内存很小,基本上不会被用完。
     然后我同样对read和write设置两个独立的状态链表,用m个线程来处理,所不同的是这两个表只有一个fd项,其余的数据都是保存在堆分配的全局状态表中,我对全局状态表设置很多的状态值,比如:read write readed writed needRepetRead needrepetWrite restart等等,这样我可以将其他的处理分别用新的状态链表来保持,锁不同的是全局表的状态不一样,从而达到多个处理程序协作的问题,互斥锁只存在于各个处理环节,如果读的环节慢了就可以加大读的线程数,写的慢了可以加大写的,处理的过程慢了可以加大处理的,这样方便系统后期调试优化,但是每一个环节都不会影响全局表的处理,不会因为一个线程堵塞或则死掉导致全局的状态都没法进行

初步作出来的模型同样采用sendfile +epoll情况下,经测试我的server已经略微超过nginx,下面就是进一步的规范和优化扩展的部分了

我也是刚刚转到linux下面来,polled,select是早期的两个模型,总的来说这个种都是为了到达到事件通知功能,内部实现原理不一样,所以在实际应用的过程中就可以做这样的分层:事件模型和协议处理模型分开。有很多这样的例子,nginx就是这样的,编译的时候根据不同的系统选择不同的事件通知模型,也就是说你写的程序觉大部分跟这几个函数没关系,他们只是起到检测socket事件的作用,至于内部区别你可以去看源代码,也有网上的大量说明,没必要这里再细细罗列,目前epoll在处理大量用户连接的情况下综合性能最好,少量连接(1-200个)就都差不多了,甚至pool或者select比epoll还好,这是他们实现的机制不同

Reference:

epoll为什么这么快 http://www.cppblog.com/converse/archive/2008/10/12/63836.html

linux多线程socket编程一些心得的更多相关文章

  1. 《Linux多线程服务器端编程》读书笔记第3章

    <Linux多线程服务器端编程>第3章主要讲的是多线程服务器的适用场合与常用的编程模型. 1.进程和线程 一个进程是"内存中正在运行的程序“.每个进程都有自己独立的地址空间(ad ...

  2. Linux多线程服务器端编程

    目录 Linux多线程服务器端编程 线程安全的对象生命期管理 对象的销毁线程比较难 线程同步精要 借shared_ptr实现写时拷贝(copy-on-write) 多线程服务器的适用场合与常用编程模型 ...

  3. [转载]赖勇浩:推荐《Linux 多线程服务器端编程》

    推荐<Linux 多线程服务器端编程> 赖勇浩(http://laiyonghao.com) 最近,有一位朋友因为工作需要,需要从网游的客户端编程转向服务器端编程,找我推荐一本书.我推荐了 ...

  4. 推荐《Linux 多线程服务器端编程》

    赖勇浩(http://laiyonghao.com) 最近,有一位朋友因为工作需要,需要从网游的客户端编程转向服务器端编程,找我推荐一本书.我推荐了<Linux 多线程服务器端编程——使用 mu ...

  5. LInux下socket编程学习笔记

    1.socket套接字: socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模 ...

  6. Linux下Socket编程的端口问题( Bind error: Address already in use )

    Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...

  7. linux下socket编程实例

    linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...

  8. Linux的SOCKET编程详解(转)

    Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系 ...

  9. 【ARM-Linux开发】Linux的SOCKET编程详解

    Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系 ...

随机推荐

  1. Spoj1771-Yet Another N-Queen Problem(精确覆盖)

    Description After solving Solution to the n Queens Puzzle by constructing, LoadingTime wants to solv ...

  2. Linux硬盘分区和格式化

    分区与格式化   先用fdisk分区,分区完成后再用mkfs格式化并创建文件系统,挂载,磁盘就能使用啦.   分区的原理:        MBR:主引导扇区 主分区表:64bytes,最多只能分四个主 ...

  3. Live555 分析(三):客服端

    live555的客服端流程:建立任务计划对象--建立环境对象--处理用户输入的参数(RTSP地址)--创建RTSPClient实例--发出DESCRIBE--发出SETUP--发出PLAY--进入Lo ...

  4. hdu 1429 胜利大逃亡(续)(bfs+状态压缩)

    Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带 ...

  5. HtmlHelper扩展 及 页面编码化

    Html.Encode 新建Action,命名为HtmlEncodeDemo 将含有特殊字符的值传递给View视图 <%= ViewData["script"] %> ...

  6. DoTween学习笔记(一)

    DOTween是一个快速,高效,完全统一的类型安全的对象属性动画引擎,免费开源,大量的高级特性. DoTween兼容Unity4.5以上的版本,支持的平台: Win, Mac, Unity WebPl ...

  7. Apache、Tomcat、JBoss、WebLogic的区别与关系

    Weblogic: 是一个企业级的应用服务器,其中包括j2ee中的各类应用如jsp,servlet,ejb等 Tomcat:   是一个初级的应用服务器,支持sp和servlet,不支持EJB,如需E ...

  8. 再一次强调,ORACLE外键必须加索引

    外键加索引是常识,必须牢记.本来不想写这样的简单案例.可是连续遇到好几起外键不加索引导致性能问题,所以还是写一下. 一个兄弟问我 delete from Sa_Sales_Comm_Detail s  ...

  9. C++ - 容器(container)的erase()函数

    容器(container)的erase()函数 本文地址: http://blog.csdn.net/caroline_wendy/article/details/23996013 容器(contai ...

  10. VC调试笔记

    1.windows-32调试: ①使用map文件根据崩溃地址寻找对应的源代码文件和行号 勾选project->settings->link->General mapfile,对应的P ...