课程咨询 :13623629309

太原PHP培训 > 达内新闻 > 太原php培训班:网络协程编程(一)
  • 太原php培训班:网络协程编程(一)

    发布:太原PHP培训      来源:达内新闻      时间:2016-08-23

  • 一、背景

    为什么需要网络协程?

    1、协程/纤程并不是一个新概念

    2、大并发、高性能对于服务端的高要求

    3、移动设备的快速增长加大了服务端大并发压力

    4、Go 语言的兴起将协程带到了一个新的高度

    支持协程的编程语言:

    1、Go 语言,非常容易支持大并发、高性能

    2、Python 语言

    3、Erlang 语言

    4、Lua 语言

    。。。。。。

    为什么要设计一套 C/C++ 网络协程库?

    1、学习一部门语言的成本要远高于学习一个库

    2、C/C++ 程序员多年的经验积累损耗巨大

    3、C/C++ 综合运行效率高

    二、关于并发

    – 虽已进入多核时代,但服务器的 CPU 核心总是有限的

    – 当进程/线程数越多操作系统的调度算法就越低效

    – TCP长连接及连接池的存在,造成服务端80%以上的连接是空闲的

    为支持并发,我们需要采用:

    1、多进程模式:支持并发能力非常有限,如 Postfix,Xinetd;

    2、多线程模式:比多进程模式有提高,但依然有限,如 Mysql;

    3、非阻塞模式:性能高,但编程复杂度极高,如 Nginx,Redis;

    4、基于事件的多线程模式:并发度有较大提高,但编程提升依然有限,如 acl 中的 master_threads 服务模式;

    三、设计目标

    我们需要一种新的编程模式来满足C/C++程序员:

    1、支持大并发、高性能,较低的资源使用率

    2、较低的编程复杂度:顺序思维模式

    3、适合多数应用场景,提供丰富且简单易用的接口

    4、与第三方网络库无缝集成,无需修改第三方库

    四、一个简单的协程示例

    太原php培训机构

    1、创建协程类似于创建线程

    2、支持大并发、高性能

    3、顺序性编程方式

    4、无需更改第三方库

    5、仅使用一个线程资源

    五、协程的调度方式

    1、上下文切换

    通过操作系统提供的 API 完成:getcontext、makecontext、swapcontext、setcontext;

    或 自己通过汇编语言来实现协程运行栈空间的切换

    实现库举例:libtask,boost,libgo, libco,coroutine 等

    2、信号跳转

    通过系统提供的 API 完成:siglongjmp、longjmp、setjmp、sigsetjmp 等

    实现库举例:libmill,st ,coroutine 等

    六、协程切换方式

    太原php培训机构

    七、网络协程调度

    太原php培训班

    1、IO事件协程监控所有的IO事件

    2、网络协程运行时遇到IO阻塞,则被挂起,其IO句柄由IO事件协程监控

    3、IO事件发生时,其绑定的协程被再次唤醒

    八、如何与第三方库无缝集成

    1、HOOK IO相关API

    读 API:read/readv/recv/recvfrom/recvmsg

    写 API:write/writev/send/sendto/sendmsg

    其它 API:pipe/popen/pclose/open/close/fcntl

    2、HOOK 网络相关API

    socket/socketpair/bind/listen/accept/connect

    poll/select/epoll_create/epoll_wait/epoll_ctl

    gethostbyname/gethostbyname_r

    通过 HOOK 系统底层 API,可以实现:

    1、直接接管第三方库(如:mysql/http/redis 等库)的网络连接及通信过程

    2、直接接管第三方库的域名解析过程

    3、将第三方网络阻塞过程协程化,在协程库底层转化为非阻塞过程

    将mysql库协程化的例子参见:acl/lib_fiber/samples/mysql

    九、为何要 HOOK 很多系统API

    1、poll/select 为网络编程中常用系统 API

    2、很多第三方网络库用 poll/select 模拟IO超时

    3、epoll 在 reactor 类应用(如:聊天)方面比较广泛

    4、gethostbyname 在域名解析方面应用广泛

    5、listen 需要将监听描述字设为非阻塞模式

    6、connect 需要将连接描述字设为非阻塞模式

    7、bind/socket/socketpair/。。。为便于将出错号与协程绑定

    十、基于协程的 errno

    因为每个线程中存在大量协程,当某个协程的IO过程出错时,如果实现不同协程之间的 errno 是相互隔离的?

    — 在 Linux 平台下直接 HOOK __errno_location 系统函数

    参见:/usr/include/bits/errno.h

    extern int *__errno_location (void) __THROW __attribute__ ((__const__));

    #define errno (*__errno_location ())

    针对进程内全局变量:errno,操作系统将该变量定义为一个函数指针地址,函数内部会通过线程局部变量方式给每一个线程分配一个 error 对象

    因此,通过 hook __errno_location 函数,在协程库里给每个协程一个协程局部变量,实现了 errno 全局变量的协程安全性

    十一、内存安全检测

    配合 valgrind 做内存检测:

    – valgrind 与 xxxcontext 的不兼容性

    – 需下载 valgrind 开发包,调用 VALGRIND_STACK_REGISTER通知

    valgrind 跳过检测该内存区域

    – 检测时在 Makefile 里打开 –DUSE_VALGRIND 编译选项,重新编译 lib_fiber.a

    达内时代科技集团致力于培养面向电信和金融领域JavaC++C#/.Net3G/Android3G/IOSPHP、嵌入式、软件测试、UID、网络营销、网络工程、会计、UEDwebUnity3D、大数据、童程童美等17大方向中高端软件人才课程与少儿教育课程。选择太原php培训,不再孤军奋战,轻轻松松做IT高薪白领。太原达内培训带领有明确目标的学子迈向成功之路!想找工作的求职者可以加QQ3373924515(太原达内就业服务部)咨询了解。

上一篇:太原php培训机构:程序员该如何维护健康的人际关系?

下一篇:太原php培训机构:网络协程编程

最新开班日期  |  更多

php高级开发名企定制班(剩2个名额)

php高级开发名企定制班(剩2个名额)

开班日期:12-30

php高级开发周末班(剩5个名额)

php高级开发周末班(剩5个名额)

开班日期:12-30

php高级开发免费试听(剩5个名额)

php高级开发免费试听(剩5个名额)

开班日期:12-30

更多高级开发工程师精品班

更多高级开发工程师精品班

开班日期:12-30

  • 地址:山西省太原市小店区学府街长治路高新国际A座24层
  • 课程培训电话:13623629309     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56

    在线客服系统