Linux高性能服务器编程:高性能服务器程序框架
服务器有三个主要模块:
(1)I/O处理单元
(2)逻辑单元
(3)存储单元
1.服务器模型
C/S模型
逻辑:服务器启动后,首先创建一个或多个监听socket,并调用bind函数将其绑定到服务器感兴趣的端口上,然后调用listen函数等待客户连接。
服务器运行稳定后,客户端就可以调用connect函数向服务器发起连接了。
P2P模型
P2P模型使得每台机器在消耗服务的同时也给别人提供服务,这样资源能够充分、自由的共享。
2.服务器编程框架
包含:
I/O处理单元 请求队列 逻辑单元 请求队列 网络存储单元
I/O处理单元:处理客户连接,读写网络数据
逻辑单元:业务进程或线程
网络存储单元:本地数据库、文件或缓存
请求队列:各单元之间的通信方式
3. I/O模型
阻塞I/O执行的系统调用可能因为无法立即完成而被操作系统挂起,知道等待的事件发生为止。可能阻塞的系统调用包括:accept,send,recv和connect。
非阻塞I/O执行的系统调用则总是立即返回,而不管时间是否发生。如果事件没有立即发生,这些系统调用就返回-1,和出错的情况一样。必须根据errno来区分这两种情况。
对accept,send和recv而言,事件未发生时errno通常被设置成EAGAIN或者EWOULDBLOCK:对connect而言,errno则被设置成EINPROGRESS。
显然,只有在事件已经发生的情况下操作非阻塞I/O,才能提高程序的效率。I/O通知机制有:I/O复用和SIGIO信号。
I/O复用:应用程序通过I/O复用函数向内核注册一组事件,内核通过I/O复用函数把其中就绪的事件通知给应用程序。Linux上常用I/O复用函数是selcet、poll和epoll_wait。I/O复用本身是阻塞的,能提高效率的原因是
它们具有同时监听多个I/O事件的能力。
SIGIO信号:可以为一个目标文件描述符指定宿主进程,那么被指定的宿主进程将捕获到SIGIO信号。这样,当目标文件描述符上有事件发生时,SIGIO信号的信号处理函数将被触发,可以在该信号处理函数中对目标文件描述符执行非阻塞I/O操作了。
理论上说,阻塞I/O,I/O复用和信号驱动I/O都是I/O同步模型。在这三种模型中,I/O的读写操作,都是I/O事件发生之后,由应用程序来完成的。
对异步I/O而言,用户可以直接对I/O执行读写操作,这些操作告诉内核用户读写缓冲区的位置,以及I/O操作完成之后内核通知应用程序的方式,异步I/O的读写操作总是立即返回,而不论I/O是否是阻塞的,因为真正的读写操作已经由内核接管。
也就是说,同步I/O模型要求用户代码自行执行I/O操作(将数据从内核缓冲区读入用户缓冲区,或将数据从用户缓冲区写入内核缓冲区),而异步I/O机制则由内核来执行I/O操作(数据在内核缓冲区和用户缓冲区之间的移动是由内核在“后台”完成的)。
同步I/O向应用程序通知的是I/O就绪事件,而异步I/O向应用程序通知的是I/O完成事件。
4.两种高效的事件处理模式
使用同步I/O模型实现Reactor模式:
(1)主线程往epoll内核事件表中 注册socket上的读就绪事件。
(2)主线程调用epoll_wait等待socket上有数据可读。
(3)当socket上有数据可读时,epoll_wait通知主线程,主线程将socket事件放入请求队列中。
(4)睡眠在请求队列上的某个工作线程被唤醒,从socket读取数据,并处理客户请求,然后往epoll内核事件表中注册该事件的写就绪事件。
(5)主线程调用epoll_wait等待socket可写。
(6)当socket可写时,epoll_wait通知主线程。主线程将socket可写事件放入请求队列。
(7)睡眠在请求队列上的某个工作线程被唤醒,它往socket上写入服务器处理客户请求的结果。
Proactor模式
Proactor模式将所有I/O操作都交给主线程和内核来处理,工作线程仅仅负责业务逻辑。
半同步/半异步:
同步线程用于处理客户逻辑,异步线程用于处理I/O事件。
异步线程由主线程充当。负责监听所有socket上的事件。若监听socket上有可读事件发生,即有新的连接到来,主线程就接受之以得到新的连接socket,然后往epoll内核事件表中注册该socket上的读写事件。
如果连接socket上有读写事件发生,即有新的客户请求到来或有数据要发送到客户端,主线程就将该连接socket插入请求队列中。所有工作线程都睡眠在请求队列上,当有任务带来时,将通过竞争获得任务的接管权。
缺点:
主线程和工作线程共享请求队列。主线程往请求队列中添加任务,或者工作线程从请求队列中取出任务,都需要对请求队列加锁保护,从而拜拜浪费CPU时间。
每个工作线程在同一时间只能处理一个客户请求。
Linux高性能服务器编程:高性能服务器程序框架的更多相关文章
- Linux 高性能服务器编程——高性能服务器程序框架
问题聚焦: 核心章节. 服务器一般分为如下三个主要模块:I/O处理单元(四种I/O模型,两种高效事件处理模块),逻辑单元(两种高效并发模式,有效状态机)和存储单元(不讨论). 服务器模 ...
- 【转】MMORPG游戏服务器技能系统设计:表格字段与技能程序框架
本文主要从一个程序员的角度阐述一下mmorpg服务器技能系统的程序框架设计,最近在做这个,就当做一个总结吧,其中某些概念可能没有解释清楚,欢迎大家拍砖讨论~ 技能其实是战斗系统的一个组成部分,战斗基本 ...
- linux高性能服务器编程 (八) --高性能服务器程序框架
第八章 高性能服务器编程框架 这一章主要介绍服务器的三个主要模块: I/O处理单元.逻辑单元.存储单元.另外服务器的模型有:C/S模型和P2P模型.虽然服务器模型比较多,但是其核心框架都一样,只是在于 ...
- Linux 高性能服务器编程——Linux服务器程序规范
问题聚焦: 除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范. 工欲善其事,必先利其器,这篇主要来探 ...
- 开源软件实践之linux高性能服务器编程框架和选型
很多人学习编程技术一般都通过一本编程语言的入门书籍,然后尝试做一些例子和小项目.但是这些都不能让我们深入的学习很多的编程技巧和高深技术,当然这个时候很多有经验的学习人员就会告诉大家,找一个好的开源软件 ...
- Linux 高性能服务器编程——多线程编程
问题聚焦: 在简单地介绍线程的基本知识之后,主要讨论三个方面的内容: 1 创建线程和结束线程: 2 读取和设置线程属性: 3 线程同步方式:POSIX信号量,互斥锁和条件变量 ...
- linux高性能服务器编程
<Linux高性能服务器编程>:当当网.亚马逊 目录: 第一章:tcp/ip协议族 第二章:ip协议族 第三章:tcp协议详解 第四章:tcp/ip通信案例:访问Internet 第五章: ...
- Linux 高性能服务器编程——多进程编程
问题聚焦: 进程是Linux操作系统环境的基础. 本篇讨论以下几个内容,同时也是面试经常被问到的一些问题: 1 复制进程映像的fork系统调用和替换进程映像的exec系列系统调 ...
- Linux 高性能服务器编程——I/O复用
问题聚焦: 前篇提到了I/O处理单元的四种I/O模型. 本篇详细介绍实现这些I/O模型所用到的相关技术. 核心思想:I/O复用 使用情景: 客户端程序要同时处理多个socket ...
随机推荐
- POJ 3090 欧拉函数
求一个平面内可见的点,其实就是坐标互质即可,很容易看出来或者证明 所以求对应的欧拉函数即可 #include <iostream> #include <cstdio> #inc ...
- CharacterEncodingFilter详解及源码解析
字符编码过滤器 (Spring框架对字符编码的处理) 基于函数回调,对所有请求起作用,只在容器初始化时调用一次,依赖于servlet容器. web.xml配置文件 <filter> &l ...
- VS2013+HALCON13
HALCON安装与配置(VS2013+HALCON13) 2017-06-23 16:08:25 坚强的羊脂球 阅读数 4574更多 分类专栏: HALCON 配置主要分为三部分: 1)VS调用H ...
- 关于Arduino MEGA2560 看门狗对bootloader的依赖
bootloader在Arduino中起着至关重要的位置,arduino-1.5.6-r2版本中的bootloader对看门狗(watchdog)的bug进行了修复:mega2560其实就是使用的AV ...
- 二十五、JavaScript之查找字符串中的字符串indexOf和lastIndexOf的用法
一.代码如下 二.效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" conten ...
- C#不显示在任务栏
在我用c#写一些小程序是总是希望,程序窗体不在任务栏上显示程序的窗体,c# Form提供了一个 属性值可以很好的解决这个问题 这个属性就是 ShowInTaskbar 在微软的官方声明格式为: pub ...
- C#的listview
listView1.Items.Clear(); ListViewItem listitem = new ListViewItem(字符串);//这是第一列的内容,需要,而且必须通过构造方法添加 ; ...
- Day 21:网络编程(2)
以课程中feiQ为例,feiQ作为一个典型的网络编程应用,用一段代码尝试给自己的发送消息 import java.io.IOException; import java.net.DatagramPac ...
- 打包|zip
原始:gzip zip -r ./gzip.zip ./gzip/* adding: gzip/split_10.gz (deflated 2%) adding: gzip/split_11.gz ( ...
- UVA - 11181 Probability|Given (条件概率)
题意:有n个人,已知每个人买东西的概率,求在已知r个人买了东西的条件下每个人买东西的概率. 分析:二进制枚举个数为r的子集,按定义求即可. #include<cstdio> #includ ...