太原PHP培训
达内太原php培训中心

0351-5608878

热门课程

太原php培训班:网络协程编程(一)

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

一、背景

为什么需要网络协程?

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培训资源站

太原PHP编程开发并发编程槽与坑

Php开发规划自己的路

太原php培训老生常谈php

选择城市和中心
贵州省

广西省

海南省

台湾