1.libevent、码分libev框架介绍
2.网络I/O库总结(libevent,码分libuv,libev,libeio)
3.史上最详细的网络编程实战教程
4.C语言10个经典开源项目
5.Gevent源码剖析(二):Gevent 运行原理
libevent、libev框架介绍
本文深入讲解了libevent的码分API,并剖析了libevent的码分evbuffer源码。libevent、码分libev和libuv都是码分txl相册获取源码C语言实现的异步事件库,主要负责注册异步事件、码分检测异步事件,码分并根据事件的码分触发先后顺序调用相应的回调函数处理事件。这些事件包括网络I/O事件、码分定时事件以及信号事件,码分共同驱动服务器运行。码分
libevent和libev主要封装了与操作系统交互的码分简单事件管理接口,让开发者无需关注平台差异,码分只需处理事件的码分具体逻辑。libev改进了libevent的架构决策,如消除全局变量的使用,采用回调函数传递上下文,构建不同的数据结构以降低事件耦合性,使用最小四叉堆作为计时器,从而实现高效管理。然而,libevent和libev在window平台的支持较差,因此libuv应运而生,基于libev,尤其在window平台上更好地封装了iocp,node.js即基于libuv。
在libevent的编译安装过程中,首先从git下载release-2.1.-stable.tar.gz,双动量均线源码然后在编译程序时指定库名:-levent。由于头文件和库文件已经复制至系统路径,因此在编译时无需额外指定-I和-L。
libevent的封装层次分为网络封装和解决的问题。网络封装包括IO检测和IO操作,解决的问题涉及连接建立(如最大连接数、黑白名单等)和连接断开,以及数据的到达与发送。如果不想手动操作IO事件,libevent会管理读写I/O处理,使开发者只需处理逻辑,无需关心边界问题。
libevent提供了事件检测与操作的封装。事件检测是低层封装,由libevent负责,用户自定义IO操作。该层次封装了事件管理器操作和事件接口。事件管理器event_base用于构建事件集合,检测事件就绪情况。释放管理器使用event_base_free,event_reinit用于重置,event_get_supported_methods查看支持的方法。
事件循环通过event_base_dispatch和event_base_loop实现,等待事件产生,提供类似epoll红黑树循环的功能。事件循环终止使用event_base_loopbreak和event_base_loopexit,前者在事件回调执行后终止,后者立即终止。武林ol手游源码
事件对象通过event_new创建,event_free销毁。注册与注销事件使用event_add和event_del,事件驱动的核心思想是libevent的核心功能。
libevent事件对象包括只使用事件检测、IO操作自处理的Demo。此外,自带缓冲的事件-bufferevent介绍其作为event的高级版本,拥有两个缓冲区和三个回调函数,分别用于读取、写入和事件处理。
bufferevent提供读写数据到缓冲区的封装,三个回调函数分别处理读取、写入和事件触发。构建、销毁bufferevent对象,以及连接操作、设置回调等。
事件类型注册与注销使用bufferevent_enable/disable,获取读写缓冲区使用bufferevent_get_input和bufferevent_get_output,数据分割使用evbuffer_readln和固定长度读取使用evbuffer_remove。
对于bufferevent,一个文件描述符对应两个缓冲区和三个回调函数,文件描述符用于与客户端通信,非监听文件描述符。两个缓冲区指读缓冲区和写缓冲区,三个回调分别对应读操作、写操作和事件触发。正版购物小程序源码
链接监听器-evconnlistener封装底层socket通信函数,如socket、bind、listen、accept。创建监听器后,等待新客户端连接,调用用户指定的回调函数。构建监听器使用evconnlistener_new_bind,回调函数evconnlistener_cb接收与客户端通信的描述符和连接对端地址。
信号事件在libevent中与网络事件相似,通过epoll监听。定时事件和网络事件的处理机制基于最小堆与epoll_wait,通过源码分析可深入了解流程。
evbuffer作为libevent底层实现的链式缓冲区,用于bufferevent事件中的数据读写。每个evbuffer由链表组成,包含关键成员和实现细节。evbuffer的优点在于高效处理数据移动和内存浪费,缺点是数据在不连续内存中存储,可能导致多次io。libev关注具体网络IO事件、定时事件和信号事件,提供API如ev_io_init、ev_io_start、ev_timer_start和ev_run。通过libev宏定义封装,开发者能使用与libevent类似的该站点已暂停源码接口。
网络I/O库总结(libevent,libuv,libev,libeio)
Libevent
Libevent 是一个基于事件驱动模型的非阻塞网络库,用于构建高速、可移植的非阻塞 IO 应用。广泛应用于 memcached、Vomit、Nylon、Netchat 等项目中,作为底层网络库,用于实现 TCP 或 HTTP 服务。Libevent 的 GitHub 源码可访问。
Libev
Libev 是由 Marc Lehmann 独立完成的,对不同系统非阻塞模型进行简单封装,解决了不同 API 之间的不兼容问题,保证程序在大多数 *nix 平台上运行。Libev 支持类 UNIX 系统的多种 I/O 多路复用模型,如 select、poll、epoll、kqueue、evports 等,但对于 Windows 的支持仅限于 select 模型,效率较低,性能不如 Libuv 封装的 IOCP。Libev 目标是修复 Libevent 的一些设计问题,如避免使用全局变量,提供更高效的事件类型管理。
Libuv
Libuv 是一个跨平台、高性能、事件驱动的异步 IO 库,用 C 语言编写,封装了不同平台底层的高性能 IO 模型,如 epoll、kqueue、IOCP、event ports,具有高度可移植性。Libuv 为 Node.js 设计,但因其高效模型逐渐被其他语言和项目采纳,用于底层库,如 Luvit、Julia、uvloop、pyuv 等。
Libevent、Libev、Libuv 比较
根据 GitHub 星标数,Libuv 的影响力最大,其次是 Libevent,Libev 关注较少。在优先级、事件循环、线程安全等方面,Libuv 更为现代,支持多种平台和 IO 模型,提供了更优的性能和功能。Libevent 和 Libev 分别针对不同平台和需求进行优化,Libev 旨在修复 Libevent 的问题。性能和可移植性方面,Libuv 优于 Libevent 和 Libev。
异步 IO 实现
目前 Linux 异步 IO 实现有原生异步 IO 和多线程模拟异步 IO 两种方式。原生异步 IO 支持特定场景,但不充分利用 Page cache;多线程模拟异步 IO 方式如 Glibc AIO、libeio、io_uring 等,提供更广泛的适用场景。
史上最详细的网络编程实战教程
本文通过介绍libhv——一个比libevent、libev、libuv更易用的跨平台国产网络库,旨在提供网络编程实战教程,帮助读者更好地理解TCP/UDP/SSL/HTTP/WebSocket网络编程。libhv提供了带非阻塞IO和定时器的事件循环,适用于开发TCP/UDP/SSL/HTTP/WebSocket客户端/服务端。
项目地址:github.com/ithewei/libhv
码云镜像:gitee.com/libhv/libhv.gitee.com
QQ技术交流群:
libhv博客专栏:hewei.blog.csdn.net/cat
libhv源码分析:blog.csdn.net/qu/ca
libhv教程--目录
libhv是一个跨平台网络库,适用于开发TCP/UDP/SSL/HTTP/WebSocket客户端/服务端。
libhv教程--介绍与体验
libhv是一个高性能事件循环库,寓意High-performance event loop library(高性能事件循环库)。Linux与mac用户可直接执行getting_started.sh脚本体验libhv编写的/p/cmock...
三、Libev
Libev是一个基于epoll、kqueue等OS基础设施的高效事件驱动库,使用Reactor模式处理IO事件、定时器和信号,代码量少至4.版本的多行。
下载链接: software.schmorp.de/pkg...
四、Memcached
Memcached是一个用于动态Web应用的高性能分布式内存对象缓存系统,通过缓存数据和对象减少数据库读取次数,加速动态数据库驱动网站的速度。Memcached-1.4.7版本代码量在K行左右。
下载地址: a distributed memory object caching system
五、SQLite
SQLite是一个开源的嵌入式关系数据库引擎,实现自包容、零配置,支持事务的SQL数据库,代码量约3万行,大小K。
下载地址: SQLite Home Page
六、Redis
Redis是一个使用ANSI C编写的开源数据结构服务器,代码量相对较小(4.5w行),几乎不依赖其他库,大部分为单线程。
下载地址: Redis
七、Nginx
Nginx是一款高性能的HTTP和反向代理服务器,设计简洁、功能丰富,具有低系统资源消耗的特性。已发布多年,获得广泛好评。
下载地址: http://nginx.org/en/download.html
八、UNIXv6内核源代码
UNIX V6内核源代码约为1万行,适合初学者理解。与现代操作系统内核源代码(如Linux的万行)相比,UNIX V6源代码在可理解性上有优势。
下载地址: minnie.tuhs.org/cgi-bin...
九、NetBSD
NetBSD是一个免费的、高度移植性的UNIX-like操作系统,支持多种平台,设计简洁、代码规范,具有多项先进特性,广受好评。
下载地址: The NetBSD Project
十、Tinyhttpd
Tinyhttpd是一个超轻量型HTTP服务器,全部代码仅行(包括注释),附带一个简单的客户端,可用于理解HTTP服务器的基本原理。
下载链接: Tiny HTTPd
Gevent源码剖析(二):Gevent 运行原理
Gevent的运行原理在python2.7.5版本下,涉及多个关键概念。简单来说,它通过Greenlet类和Hub事件循环实现并发执行。以下是核心步骤:
首先,通过导入gevent模块,引入其初始化设置,greenlet的运行函数通过gevent.spawn()方法注册到Hub,这个过程包括获取Hub实例、初始化greenlet并保存函数和参数。get_hub()利用线程局部存储保证Hub的多线程一致性。
接着,greenlet通过g.start()注册到事件循环,回调事件由switch()控制,而不是直接运行函数,实现了协程的切换。Gevent提供了join()和joinall()两个入口,其中joinall()控制了整个流程。
在详细流程中,iwait()函数扮演重要角色,通过创建Waiter对象,将协程的switch()链接到目标,通过waiter.get()控制协程执行和返回。Hub事件循环与运行协程通过waiter.get()和waiter.switch()协同工作,实现了并发执行。
目标协程的执行涉及事件循环的启动,通过Cython调用libev库执行。目标函数在run()中执行,并通过_report_result()和_report_error()处理结果或异常。"绿化"函数是实现并发的关键,它们允许在等待I/O操作时释放控制权,从而实现多任务并发。
总的来说,Gevent的运行涉及复杂的协程调度和事件驱动,虽然本文仅触及表面,但其背后的并发机制和技术细节更为丰富,包括异常处理和大量"绿化"函数的使用,这将在后续深入探讨。