libevent程序开发

libevent程序开发
libevent程序开发

一、libevent程序开发

1.认识libevent

libevent是一个开源的库;

libevent是一个事件触发的网络库;

libevent是一个reactor事件驱动机制模型;

libevent支持用户使用三种类型的事件,分别是网络IO、定时器、信号三种;

适用于windows、linux、bsd等多种平台;

内部使用select、epoll、kqueue等系统调用管理事件机制。

著名分布式缓存软件memcached也是libevent based,Google 的chrome浏览器背

后的引擎Chromium 也是用了libevent。而且libevent在使用上可以做到跨平台,

而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。(百度百

科)

2.组要组成

libevent包括事件管理、缓存管理、DNS、HTTP、缓存事件几大部分。

事件管理包括各种IO(socket)、定时器、信号等事件;

缓存管理是指evbuffer功能;

DNS是libevent提供的一个异步DNS查询功能;

HTTP是libevent的一个轻量级http实现,包括服务器和客户端。

libevent也支持ssl,这对于有安全需求的网络程序非常的重要,但是其支持不是

很完善,比如http server的实现就不支持ssl。

3.Reactor模型

3.1框架概述

在Reactor模式中,有5个关键的参与者。

(1)描述符(handle):由操作系统提供,用于识别每一个事件,如Socket描述符、

文件描述符等。在Linux中,它用一个整数来表示。事件可以来自外部,如来自客

户端的连接请求、数据等。事件也可以来自内部,如定时器事件。

(2)同步事件分离器(demultiplexer):是一个函数,用来等待一个或多个事件的

发生。调用者会被阻塞,直到分离器分离的描述符集上有事件发生。Linux的select

函数是一个经常被使用的分离器。

(3)事件处理器接口(event handler):是由一个或多个模板函数组成的接口。这

些模板函数描述了和应用程序相关的对某个事件的操作。

(4)具体的事件处理器:是事件处理器接口的实现。它实现了应用程序提供的某个

服务。每个具体的事件处理器总和一个描述符相关。它使用描述符来识别事件、识

别应用程序提供的服务。

(5)Reactor 管理器(reactor):定义了一些接口,用于应用程序控制事件调度,

以及应用程序注册、删除事件处理器和相关的描述符。它是事件处理器的调度核心。

Reactor管理器使用同步事件分离器来等待事件的发生。一旦事件发生,Reactor

管理器先是分离每个事件,然后调度事件处理器,最后调用相关的模板函数来处

理这个事件。

3.2Reactor事件处理流程

4.Libevent框架及事件处理流程

4.1libevent框架

4.2libevent事件处理流程

libevent 库的核心结构 event 4.3libevent对event的管理

struct event {

TAILQ_ENTRY (event) ev_next; /*ev_next就是该事件在链表中的位置*/

TAILQ_ENTRY (event) ev_active_next; /*所有的激活事件放入到链表active list 中, 指明了event在active list中的位置*/

TAILQ_ENTRY (event) ev_signal_next; /*signal事件在signal事件链表中的位置*/

unsigned int min_heap_idx; /* 管理超时 */

struct event_base *ev_base;/* 该事件所属的反应堆实例*/

int ev_fd;/* 对于 I/O 事件,是绑定的文件描述符;对于 signal 事件,是绑定的信号;*/

short ev_events;/* event关注的事件类型*/

short ev_ncalls; /*事件就绪执行时,调用 ev_callback 的次数,通常为 1;*/ short *ev_pncalls; /* 允许回调函数中删除的事件*/

struct timeval ev_timeout;

int ev_pri; /* 事件优先级 */

void (*ev_callback)(int, short, void *arg); /*event 的回调函数*/

void *ev_arg; /*表明可以是任意类型的数据,在设置 event 时指定;*/

int ev_res; /*记录了当前激活事件的类型; */

int ev_flags; /* libevent 用于标记 event 信息的字段,表明其当前的状态,*/

};

ev_events: event关注的事件类型,它可以是以下3种类型:

I/O事件: EV_WRITE和EV_READ

定时事件: EV_TIMEOUT

信号: EV_SIGNAL

辅助选项: EV_PERSIST,表明是一个永久事件

5.libevent使用流程

1)初始化libevent库:

event_init();

2)初始化event_base:

方法一:struct event_base * base = event_init();

方法二:struct event_base * base = event_base_new();

3)初始化事件event:

struct event *ev;

void event_set(struct event *ev, int fd, short event, void (*cb)(int, short, void *), void *arg)

ev:执行要初始化的event对象;

fd:该event绑定的“句柄”,对于信号事件,它就是关注的信号;

event:在该fd上关注的事件类型,它可以是EV_READ, EV_WRITE, EV_SIGNAL;

cb:这是一个函数指针,当fd上的事件event发生时,调用该函数执行处理,它有三个参数,调用时由event_base负责传入,按顺序,实际上就是event_set

时的fd, event和arg;

arg:传递给cb函数指针的参数;

4)设置event从属的event_base:指明event要注册到哪个event_base实例上

event_base_set(base, &ev);

5)注册event_base:

int event_add(struct event *ev, const struct timeval *timeout);

参数: ev:指向要注册的事件;

tv:超时时间;

函数将 ev 注册到 ev->ev_base 上,事件类型由 ev->ev_events 指明,如果

注册成功, ev将被插入到已注册链表中;如果 tv 不是 NULL,则会同时注册

定时事件,将 ev 添加到 timer堆上;

这一步相当于调用Reactor::register_handler()函数注册事件。

6)程序进入无限循环,等待就绪事件并执行事件处理:

int event_base_dispatch(struct event_base* base);

一直运行,直到没有已经注册的事件了,或者调用event_base_loopexit或者

event_base_loopbreak为止。

6.例子:定时

struct event ev;

struct timeval tv;

void time_cb(int fd, short event, void *argc)

{

printf("timer wakeup/n");

event_add(&ev, &tv); // reschedule timer

}

int main()

{

struct event_base *base = event_init();

https://www.360docs.net/doc/ca7115895.html,_sec = 10; // 10s period

https://www.360docs.net/doc/ca7115895.html,_usec = 0;

evtimer_set(&ev, time_cb, NULL);// 相当于event_set(&ev, -1, 0, timer_cb, NULL);

event_add(&ev, &tv);

event_base_dispatch(base);

}

7.例子:I/O伪代码

#define PORT 25341

void on_accept(int sock, short event, void* arg)

{

//相应操作

}

int main(int argc, char* argv[])

{

struct sockaddr_in my_addr;

int sock;

sock = socket(AF_INET, SOCK_STREAM, 0);

int yes = 1;

setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

memset(&my_addr, 0, sizeof(my_addr));

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(PORT);

my_addr.sin_addr.s_addr = INADDR_ANY;

bind(sock, (struct sockaddr*)&my_addr, sizeof(struct sockaddr));

listen(sock, BACKLOG);

struct event listen_ev;

base = event_base_new();

event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL);

event_base_set(base, &listen_ev);

event_add(&listen_ev, NULL);

event_base_dispatch(base);

return 0;

}

8.例子:信号伪代码

static void signal_cb(int fd, short event, void *arg)

{

//相应操作

}

int main (int argc, char **argv)

{

/* Initalize the event library */

event_init();

struct event signal_int;

event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb, &signal_int);

event_add(&signal_int, NULL);

event_dispatch();

}

9.Bufferevent、evconnlistener、libevent的DNS、libevent多线程

9.1 Bufferevent

struct bufferevent *bev;

evutil_make_socket_nonblocking(sockt);//设置非阻塞

bev = bufferevent_socket_new(base, sockt, BEV_OPT_CLOSE_ON_FREE);

bufferevent_setcb(bev, on_client_recvmessage_data_cb, NULL, NULL, NULL);

bufferevent_enable(bev, EV_READ);

struct evbuffer *input = bufferevent_get_input(bev);//取出bufferevent中的input

struct evbuffer *output = bufferevent_get_output(bev);//取出bufferevent 中output

9.2 evconnlistener

struct evconnlistener *evconnlistener_new(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, evutil_socket_t fd);

struct evconnlistener *evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, const struct sockaddr *sa, int socklen);

void evconnlistener_free(struct evconnlistener *lev);

两个evconnlistener_new*()函数都分配和返回一个新的连接监听器对象。连接监

听器使用event_base来得知什么时候在给定的监听套接字上有新的TCP连接。新

连接到达时,监听器调用你给出的回调函数。

两个函数中,base参数都是监听器用于监听连接的event_base。cb是收到新连接

时要调用的回调函数;如果cb为NULL,则监听器是禁用的,直到设置了回调函数

为止。ptr指针将传递给回调函数。flags参数控制回调函数的行为,下面会更详

细论述。backlog是任何时刻网络栈允许处于还未接受状态的最大未决连接数。更

多细节请查看系统的listen()函数文档。如果backlog是负的,libevent会试图

挑选一个较好的值;如果为0,libevent认为已经对提供的套接字调用了listen()。

两个函数的不同在于如何建立监听套接字。evconnlistener_new()函数假定已经将

套接字绑定到要监听的端口,然后通过fd传入这个套接字。如果要libevent分配

和绑定套接字,可以调用evconnlistener_new_bind(),传输要绑定到的地址和地

址长度。

要释放连接监听器,调用evconnlistener_free()。

9.3 libevent多线程

对于event_base来说,不是线程安全的。也就是说多线程不能share同一个event_base,就算是加锁操作也不行。那么这个时候就只能采取“单线程单event_base”的策略了。

9.4 libevent的DNS

「ROS与C 入门教程」搭建开发环境(QT ros_qtc_plugin)

「ROS与C 入门教程」搭建开发环境(QT ros_qtc_plugin) 说明:介绍如何搭建QT环境来开发ROS包介绍QT 安装介绍QT编译和调试ROS包测试环境:系统版本:Ubuntu14.04ROS版本:indigoQT版本:5.8.0QtCreator 安装安装前准备,安装相应的GNU开发工具集和OpenGL 开发库,请注意安装软件都需要root权限,并且要联网安装sudo apt-get install build-essential libgl1-mesa-dev libevent-pthreads-2.0.5 doxygen xorg-dev下载64位Linux 安装包为qt-opensource-linux-x64-5.8.0.run。下载地址:http://download.qt.io/archive/qt/5.8/5.8.0/qt-opensource-lin ux-x64-5.8.0.run下载的run文件不一定具有可执行权限,可以执行如下命令开启执行权限(以64位安装包为例)cd ~/tools/wget http://download.qt.io/archive/qt/5.8/5.8.0/qt-opensource-lin ux-x64-5.8.0.runchmod +x ~/tools/qt-opensource-linux-x64-5.8.0.run桌面下,点击文件,进入tools,双击 .run 安装文件直接图形界面安装注册帐号,需要邮箱和密码。可以先进入网站注册帐号,https://login.qt.io/register.默认安装在/home//Qt5.8.0下需要的Qt组件和工具,默认不安装源码默认Next完整安装,完成后点左上角的Dash home,输入“qt”如果看到Qt

memcacheQ 配置

memcacheQ 配置 什么是memcacheQ ? memcacheQ是一个基于memcache协议、BDB持久数据存储、高性能轻量级队列服务程序。 特点是: 1.简单高效,基于memcache协议,这意味着只要客户端支持memcache协议即可使用。 2.队列数据存储于BDB,持久保存。 3.并发性能好。 4.支持多条队列。 并发量较的web环境,特别是数据库写入操作过多的情景,使用队列可大大缓解因并发问题造成的数据库锁死问题。生产环境中使用效果非常好。 先决条件: memcacheQ依赖于libevent,libevent-devel和BDB (BerkleyDB) 1.先检查libevent, libevent-devel是否已经安装: rpm -qa|grep libevent 输出中必须包含libevent, libevent-deve, 如果缺失,使用以下命令安装: yum install libevent yum install libevent-devel 安装完毕再复查之:rpm -qa|grep libevent, 确保安装正确。 注意事项:libevent, libevent-devel优先使用yum安装源,光盘镜像中的rpm包安装,这样稳定性和兼容性可得到保证,网上流传的使用源码安装libevent的方法会有问题,因为很可能系统已经安装libevent, 再使用源码安装,必然导致冲突,造成意外问题,所以一定要使用上述命令检查系统是否已经安装相应的库。 2.安装BerkleyDB cd /usr/local/src wget http://219.239.89.57/deploy/db-5.2.28.tar.gz tar zxvf db-5.2.28.tar.gz cd db-5.2.28 cd build_unix ../dist/configure make make install 3.准备安装memcacheQ cd /usr/local/src wget http://219.239.89.57/deploy/memcacheq-0.2.0.tar.gz tar zxvf memcacheq-0.2.0.tar.gz cd memcacheq-0.2.0 修改configure文件,找到bdbdir="/usr/local/BerkeleyDB.4.7",修改为 bdbdir="/usr/local/BerkeleyDB.5.2", 否则执行configure时会产生找不到BDB的错误。

linux服务器部署方案

服务器部署方案 应用架构 3台服务器,操作系统要求red hat linux enterprise 4 内核版本2.6.9-67. 注:在安装的时候要安装防火墙 基础软件要求: 1. Java环境: jdk-6u13-linux-i586-rpm.bin 2. Tomcat 环境: apache-tomcat-7.0.6.tar.gz 3.MYSQlDB 环境: MySQL-server-5.1.57-1.glibc23.i386.rpm,MySQL-client-5.1.57-1.glibc23.i386.rpm 4. memcached缓存环境: libevent-1.3.tar.gz ,memcached-1.2.2.tar.gz

基础软件安装 Jdk安装: 安装步骤: 1. 新建temp文件夹在linux上比如根目录/temp 2.拷贝jdk-6u13-linux-i586-rpm.bin 到temp 下 3.chmod +x jdk-6u13-linux-i586.rpm.bin 4../jdk-6u13-linux-i586.rpm.bin 5.此时会生成文件jdk-6u13-linux-i58 6.rpm,同样给所有用户添加可执行的 权限 6.chmod +x jdk-6u13-linux-i586.rpm 7.安装程序 rpm -ivh jdk-6u13-linux-i586.rpm 8.出现安装协议等,按接受即可 设置步骤: 1.vi /etc/profile 在文件的最下面添加下面内容 JAVA_HOME=/usr/java/jdk1.6.0_13 CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar PATH=$JAVA_HOME/bin:/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin export JAVA_HOME CLASSPATH PATH 2.保存退出 3.检查 java -version 4.如果看到JVM版本及相关信息,即安装成功

lamp环境搭建_自己整理完整版

一、准备工作 在lamp环境中搭载网站 1.用winsp将网站目录copy到linux的php系统文件目录下/usr/local/apache2/htdocs 给runtime文件夹可写权限chmod 777 -R runtime 2.修改apache配置文件,修改网站首页 /usr/local/apache2/etc/http.conf 修改DirectoryIndex index.php index.html 重启apache:/usr/local/apache2/bin/apachectl restart 3.用小海豚(SQLyog) 文件/新建连接

将网页中的sql脚本导入到linux下的mysql数据库中启动mysql: 启动MySQL服务 1.用原本源代码的方式去使用和启动mysql /usr/local/mysql/bin/mysqld_safe --user=mysql & 2.重启以后还要生效: Vi /etc/rc.local /usr/local/mysql/bin/mysqld_safe --user=mysql & 进入mysql命令行 /usr/local/mysql/bin/mysql -u root -p550120

4.在windows下用浏览器访问192.168.1.1/网站目录 ============================================= 注意: 先创建/lamp文件夹 使用WinSCP 把要安装的压缩文件放到/lamp文件夹下 ./configure 执行的时候要注意不能有换行 Appche安装的时候一定要确认之前的安装已经卸载 http://192.168.255.1/index.html 这个地址要改成192.168.80.8 /usr/local/apache2/bin/apachectl start 有时候要用start有时候要用restart /usr/local/memcache/bin/memcached -umemcache & 中的-可能会有问题,要注意 1、安装编译工具gcc、gcc-c++、make 注意解决依赖关系,推荐使用yum安装,若不能联网可使用安装光盘做为yum源—— 1)编辑yum配置文件: Mount /dev/cdrom /media vi /etc/yum.repos.d/CentOS-Media.repo [c5-media] name=CentOS-$releasever - Media baseurl=file:///media * 修改为光盘挂载点 enabled=1 * 改为1意为启用 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 2)设置alias值: Vi /etc/bashrc alias yum="yum --disablerepo=\* --enablerepo=c5-media" 3)依次安装gcc、gcc-c++ Yum -y install gcc* 2、卸载系统Apache、MySQL和PHP的RPM安装包 下载前需关闭启动的服务,如httpd、mysqld service httpd stop service mysqld stop 卸载RPM包的Apache、MySQL、PHP yum remove httpd yum remove mysql 建议使用rpm –e http-1.2.3.rpm --nodeps (截断这个rpm包的依赖性) 3、关闭SELinux,允许防火墙80端口访问 1)关闭SELinux vi /etc/selinux/config SELINUX=disabled * 若安装时没有禁用SELinux ,将enforcing改为disabled 修改后需重新启动Linux方可生效! 2)关闭防火墙Netfilter/iptables 因尚未做防火墙讲解,直接简单的关闭所有防火墙设置: iptables -F * 如果没有禁用防火墙,默认80端口禁止访问 service iptables save 防火墙策略写到/etc/sysconfig/iptables,以后计算机重启再加载这个文件时,防火墙策略就会永久清空.

服务器通信技术方案

服务器通信技术方案 前言1 1.服务器通讯需要解决的问题2 1.1单台RCU设备通讯情况2 1.2上万个RCU甚至达到将近百万终端与服务器同时通讯2 1.2.1 单台服务器2 1.2.2 集群服务器2 2.目前服务器通讯主流技术方案3 2.1 网上常用主流方案简介与比较3 2.1.1 传统的socket通讯模型3 2.1.2 Windows下IOCP模型3 2.1.3 linux下epoll模型4 2.1.4 其它的网络通讯第三方开源库简介及比较5 2.2服务器集群方案6 3.根据项目情况选择最合适方案8 3.1 推荐选择linux系统下的epoll及开源库Boost::asio8 3.2 可能问题8 RCU-U设备采集数据如:车辆诊断,通过GSM基站定位,内置GPS,GPRS系统提供远程数据,对车辆各个系统的运行状况(如ENG、ABS、ETC等)实时监测状态数据等。 这些数据的网络通讯平台,则由服务器提供的通讯技术来实现,因此如何实现这种多设备数据同时接收的技术方案很重要。本文将详细介绍相关技术及提出方案。

服务器通讯需要解决的问题 单台RCU设备通讯情况 主要通讯数据: 设备端,刚连接时登陆验证(设备端信息验证); 设备端,诊断数据及其它采集数据上传到服务器(估计频率每秒发一次); 服务器端,发送指令,实现对设备端的远程配置; RCU设备工程师估计的数据: 1每个RCU设备每秒钟产生一条数据,每条数据大概100个字节左右(0.1K左右); 从上数据显示如果达到: 100万级别的RCU用户量,需要服务器有近百兆的网络带宽吞吐量。 1000万级别的RCU用户量,需要服务器有近千兆的网络带宽吞吐量。 上万个RCU甚至达到将近百万终端与服务器同时通讯 1.2.1单台服务器 如果按照经典的server/client通讯模型,当有一个设备通过(TCP/UDP)连接服务器时,服务端单独开一个线程为这个设备数据服务,显然,当路数越多,我们的设备又是长连接方式,很快服务器将在设备近千路时服务器资源将达到上限,并且存在大量线程切换与管理问题。这时如果我们能合理利用单台服务器资源(如:windows 下iocp 模式,linux下的epoll网络通信模式等),在更优的管理模式下,将能接更多设备的服务(网上资料预估几千路的长连接甚至硬件较好配置下达到万路以上)。上面我们能在单台服务器在较好硬件配置和软件优化的模型管理下,能解决几千路上万路设备的长连接。 1.2.2集群服务器 但是,如果几十万台甚至接近百万级别的设备数量同时访问服务端时,这个时候需要涉及到一种合理的集群服务器架构模式。理论上,为了达到1:10000的连接,可以采用Server-Client 的连接方式,而为了达到1:10000*100的连接,我们怎么办呢?一般会采用Client-> ConnServer -> LogicServer。相当于有一批服务器来合理布局解决设备的大并发通讯问题。 ConnServer在接受完Client 的连接后,将Logic Server 暴露给Client,并立刻断开连接,称之为短连接。以后的数据交互就和Conn Server没有关系了,让Logic Server 直接跟client 再长连接通讯,这种架构有很多的优势。

Libevent源码解析

libevent源码深度剖析 张亮 Email: sparling.liang@https://www.360docs.net/doc/ca7115895.html,

回想刚开始写时,就冠以“深度剖析”的名称,也是为了给自己一些压力,以期能写好这一系列文章,对libevent源代码的各方面作详细的分析;现在看来也算是达到了最初的目的。希望能给学习和使用libevent的朋友们有所帮助。 Email:sparkling.liang@https://www.360docs.net/doc/ca7115895.html, 张亮

目录 libevent源码深度剖析 (1) 目录 (3) 一序幕 (5) 1 前言 (5) 2 Libevent简介 (5) 3 学习的好处 (5) 二Reactor模式 (6) 1 Reactor的事件处理机制 (6) 2 Reactor模式的优点 (6) 3 Reactor模式框架 (6) 4 Reactor事件处理流程 (8) 5 小结 (9) 三基本使用场景和事件流程 (10) 1 前言 (10) 2 基本应用场景 (10) 3 实例代码 (11) 4 事件处理流程 (11) 5 小结 (12) 四libevent源代码文件组织 (13) 1 前言 (13) 2 源代码组织结构 (13) 3 小结 (14) 五libevent的核心:事件event (15) 1 libevent的核心-event (15) 2 libevent对event的管理 (16) 3 事件设置的接口函数 (17) 4 小结 (18) 六初见事件处理框架 (19) 1 事件处理框架-event_base (19) 2 创建和初始化event_base (20) 3 接口函数 (20) 4 小节 (23) 七事件主循环 (24) 1 阶段性的胜利 (24) 2 事件处理主循环 (24) 3 I/O和Timer事件的统一 (27) 4 I/O和Signal事件的统一 (27) 5 小节 (27) 八集成信号处理 (28) 1 集成策略——使用socket pair (28)

libevent 在linux下编译链接问题

libevent 在linux下编译链接问题 (2011-04-25 11:43:20) 转载▼ 分类:知识收集 标签: 杂谈 按照网上例子搞了个httpd的小demo(linvo_httpd.c),遇到一连串问题,努力google了半天,终于得解,记录之~ 环境: Linux 2.6.18-164.el5 libevent-1.4.13 首先用gcc编译时候报了类似下面信息的一堆错 /tmp/ccsKVcym.o: In function `main': linvo_httpd.c:(.text+0xdf): undefined reference to `event_init' linvo_httpd.c:(.text+0xf3): undefined reference to `evhttp_start' 应该是找不到编译后的libevent库文件所导致,可能是路径问题 这次在编译时加上了-levent参数后(让其到系统库中找event库),顺利编译通过 gcc -Wall linvo_httpd.c -o linvo_httpd -levent ./linvo_httpd 运行之~ 我擦,又来。。。。 ./linvo_httpd: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory 依然是路径问题找不到文件 whereis libevent 看下我的libevent默认装到哪里了 libevent: /usr/local/lib/https://www.360docs.net/doc/ca7115895.html, /usr/local/lib/libevent.so /usr/local/lib/libevent.a 哦~在/usr/local/lib/目录下 LD_DEBUG=libs ./linvo_httpd -v 看下demo程序究竟是到哪里去找的该文件 32372: find library=libevent-1.4.so.2 [0]; searching 32372: search cache=/etc/ld.so.cache 32372: search path=/lib/tls/i686/sse2:/lib/tls/i686:/lib/tls/sse2:/lib/tls:/lib/i686/sse2:/lib/i686:/lib/sse2:/lib:/usr/lib/ tls/i686/sse2:/usr/lib/tls/i686:/usr/lib/tls/sse2:/usr/lib/tls:/usr/lib/i686/sse2:/usr/lib/i686:/usr/lib/sse2 :/usr/lib (system search path) 32372: trying file=/lib/tls/i686/sse2/libevent-1.4.so.2 32372: trying file=/lib/tls/i686/libevent-1.4.so.2 32372: trying file=/lib/tls/sse2/libevent-1.4.so.2 32372: trying file=/lib/tls/libevent-1.4.so.2 32372: trying file=/lib/i686/sse2/libevent-1.4.so.2

黑马程序员C语言教程:libevent

标题:深入浅出-服务器高并发库libevent (一) 1安装 libevent是一个开源的高并发服务器开发包,官方地址https://www.360docs.net/doc/ca7115895.html,/ libevent目前有两个版本一个是1.4系列版本,一个是2.0系列版本。 我们可以在官方网站上看到类似有个stable表示稳定版本。 libevent-1.4.15-stable.tar.gz 对于初学者学习,建议从1.4版本学起。 在安装libevent之前先判断本电脑是否已经安装了 通过指令 ls -al /usr/lib|grep libevent 如果没有任何信息则表示没有安装,有的话如果发现libevent是1.3以下版本,则可以同过执行rpm -e libevent —nodeps 进行卸载。如果是其他操作系统使用其他对应卸载指令即可。 对于下好的tar包,通过 tar -zxvf libevent-release-1.4.15-stable.tar.gz 指令解压。 然后执行./configure命令,但是有的包可能没有configure文件,却存在一个autogen.sh 脚本,运行这个脚本。 (如果运行不起来请安装autoconf包)

然后 ./configure–prefix=/usr make sudo make install 安装完之后执行 ls -al /usr/lib/|grep libevent 如果发现有libevent文件库存在就代表安装完毕。 2 简单的libevent服务器 我们通过连接libevent库来进行管理libevent库,所以在使用gcc或者g++编译的时候最后需要加上-levent 下面是一个简单的libevent服务器。 #include #include #include #include #include #include #include #include #include using namespace std;

黑马程序员C语言教程:深入浅出-服务器高并发库libevent

标题:深入浅出-服务器高并发库libevent (二) 上一章,我们简单介绍了libevent的环境的安装,和简单的事例。 现在先不要着急分析他的代码,在这里我首先要介绍一个专业名词“Reactor 模式”。 2.1 Reactor的事件处理机制 我们应该很清楚函数的调用机制。 1.程序调用函数 2.函数执行 3.程序等待函数将结果和控制权返回给程序 4.程序继续处理和执行 Reactor 被翻译成反应堆,或者反应器。Re-actor 发音。 他是一种事件驱动机制。和普通函数调用的不同之处在于,应用程序不是主动的调用某刻API完成处理,而是恰恰相反,reactor逆置了事件的处理流程,应用程序需要提供相应的接口注册到reacotr上。如果相应的事件发生。Reacotr将主动调用应用程序注册的接口,这些接口就是我们常常说的“回调函数”。 我们使用libevent框架也就是想利用这个框架去注册相应的事件和回调函数。当这些事件发生时,libevent会调用这些注册好的回调函数处理相应的事件(I/O 读写、定时和信号)

通过reactor调用函数,不是你主动去调用函数,而是等着系统调用。 一句话:“不用打电话给我们,我么会打电话通知你”。 举个例子,你去应聘某xx公司,面试结束后。 “普通函数调用机制”公司的HR比较懒,不会记你的联系方式,那咋办,你只能面试完自己打电话问结果。有没有被录取啊,还是被拒绝了。 “Reacotr”公司的HR就记下了你的联系方式,结果出来后HR会主动打电话通知你。有没有被录取啊,还是悲剧了。你不用自己打电话去问,实际上你也不能,你没有HR的联系方式。 2.2 Reactor模式的优点 Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下的优点:1)响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的; 2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销; 3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;4)可复用性,reactor框架本身与具体事件处理逻辑无关,具有很高的复用性; 2.3 Reactor模式的必备条件 1)事件源 Linux上是文件描述符,Windows上就是Socket或者Handle了,这里统一称为“句柄集”;程序在指定的句柄上注册关心的事件,比如I/O事件。

Libevent框架简介

Libevent框架简介 一、前言 Libevent是一个轻量级的基于事件驱动的开源高性能网络库,适用于windows、linux、bsd等多种平台,支持多种I/O多路复用技术,iocp、epoll、poll、dev/poll、select和kqueue等。根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。 二、基础概念 学习libevent,首先得了解什么是事件驱动。 所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数)。 图一、事件驱动模型 另外关于同步异步,阻塞非阻塞的概念可以参考: http://192.168.10.106/pages/viewpage.action?pageId=1672961 三、libevent框架 Libevent框架本质上是一个典型的Reactor模式,所以只需要弄懂Reactor模型,libevent 就八九不离十了。 Reactor模式,是一种事件驱动机制。应用程序需要提供相应的接口并注册到Reactor 上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。 在Libevent中也是一样,向Libevent框架注册相应的事件和回调函数;当这些事件发生时,Libevent会调用这些回调函数处理相应的事件(I/O读写、定时和信号)。 使用Reactor模型,必备的几个组件:事件源、Reactor框架、多路复用机制和事件处理程序,先来看看Reactor模型的整体框架,接下来再对每个组件做逐一说明。

图二、Reactor模型的整体框架 图三、Reactor模型UML框架 1)事件源 Linux上是文件描述符,Windows上就是Socket或者Handle了,这里统一称为“句柄集”;程序在指定的句柄上注册关心的事件,比如I/O事件。 2)event demultiplexer——事件多路分发机制 由操作系统提供的I/O多路复用机制,比如select和epoll。程序首先将其关心的句柄(事件源)及其事件注册到event demultiplexer上;当有事件到达时,event demultiplexer会发出通知“在已经注册的句柄集中,一个或多个句柄的事件已经就绪”;程序收到通知后,就可以在非阻塞的情况下对事件进行处理了。 对应到libevent中,依然是select、poll、epoll等,但是libevent使用结构体eventop进行了封装,以统一的接口来支持这些I/O多路复用机制,达到了对外隐藏底层系统机制的目的。 3)Reactor——反应器

各式不同C++网络库对比

各式不同C++网络库对比 学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。 目前市面上存在许多开源的C/C++网络库中,各个网络库都有各自不同的特点,作为一个有专业的C++培训机构,博洋教育可以帮助大家理解和熟悉这些网络库,目前市面上常用的就那么几个,较为轻量级的有libevent,libev,还有Boost的ASIO.而在业界知名度最高的,应该是ACE了,不过是个重量级的网络库。 libevent是一个C语言写的网络库,官方主要支持的是类linux操作系统,最新的版本添加了对windows的IOCP的支持。在跨平台方面主要通过select模型来进行支持。 Boost的ASIO是一个异步IO库,封装了对Socket的常用操作,简化了基于socket程序的开发。支持跨平台。 libev是一个C语言写的,只支持linux系统的库,使用方法类似libevent,但是非常简洁,代码量是最少的一个库。跨平台支持的不好,如果你只需要在linux下面运行,那还是可以的。 ACE是一个大型的中间件产品,代码20万行左右,过于宏大,一堆的设计模式,架构了一层又一层,使用的时候,要根据情况,看你从那一层来进行使用。支持跨平台。 下面主要通过ACE网络库来分析开源的C/C++网络库,主要是因为ACE网络库在使用中,常常有学习者一直对其中的内存管理搞得一头雾水,Boost的ASIO,在内存管理方面要直观的多。下面简单地与ACE做个比较。 1.设计模式:ACE主要应用了Reactor,Proactor等。而ASIO主要应用了 Proactor.libevent为Reactor模式 2.层次架构:ACE底层是C风格的OS适配层,上一层基于C++的wrap类,再上一层是一些框架(Accpetor,Connector,Reactor,Proactor等),最上一层是框架上服务。 Boost.ASIO与之类似,底层是OS的适配层,上一层一些模板类,再上一层模板类的参数化(TCP/UDP),再上一层是服务,它只有一种框架为io_service.livevent在不同的操作系统下,做了多路复用模型的抽象,可以选择使用不同的模型,通过事件函数提供服务。

CAS集群部署(Linux)

安装CAS集群(v1.0)

目录 1部署操作 (2) 1.1硬件及部署要求 (2) 1.1.1部署图 (2) 1.2操作系统安装—SERVER1,2 .................................................................................................. 错误!未定义书签。 1.3安装M EMCACHED (2) 1.3.1安装环境 (2) 1.3.2安装步骤 (3) 1.4安装LVS (7) 1.5配置CAS集群模式 (11)

1 部署操作 1.1 硬件及部署要求 以下几种集群部署策略请根据实际情况选择确定。 (1)使用认证平台人数在3万人以下,并发5000以下,不推荐集群化部署,单台即可; 节点服务器要求(2路4核,8G 内存以上)物理机优先。 1.1.1 部署图 说明:此架构为CAS 的集群模式,考虑高并发的模式及双击热备的模式,Memcached 需要配置1-2G 内存,可以考虑单独部署服务器,可以与其中一台CAS 服务器进行一起部署。 如果Memcached 挂了或者不能访问了,CAS 服务器就不能访问。 ● CPU 类型:Intel/AMD (64位,主频2.6GHz 以上,2核及以上) ● 内存容量:4GB 及以上 ● 硬盘容量:160GB 以上,Raid 1/5 ● 网络控制器:千兆以太网卡(两块以上) ● IP (对外提供服务):3个,其中一个为虚拟ip ● 集群策略:MirrorMode ● 拓扑图: PC Smart Phone IP :Memcached 1.2 安装Memcached 1.2.1 安装环境 redhat server 6.3(64bit)/ Centos 6.3(64bit)

QCon会议笔记-架构案例和实践(理论不懂就实践)

QCon会议笔记(架构案例&实践篇) rouse整理 2009-4-13 有关大容量高并发网站架构,我参加了ebay、淘宝、优酷三家的架构实践演讲,豆瓣网和淘宝的演讲同时举行,鱼掌不可兼得,由于淘宝网属首次介绍架构,而豆瓣以前有了解,且网上资料较多,故没有参加豆瓣网的演讲,事后了解到这次豆瓣网的架构讲的比较细,不能不说是一个遗憾。现分别介绍: 《来自eBay的教训——可扩展站点的最佳实践》 Randy Shoup eBay市场架构组的杰出架构师 ebay提到了构建大型高容量系统的原则和实践,集中阐述了实现可扩展性的5个架构原则: 1、分割(按功能分离、水平切割、无状态化) 2、异步(事件队列、消息多播) 3、自动化(适应性配置、机器学习---在恰当的时间适当的地方推出合适的内容) 4、关注异常(异常捕捉、回滚、优雅降级、记录所有的错误、当系统出现严重的错误的时发消息出来,可以通过订阅消息来实现错误修正等,有点类似erLang的容错) 5、拥抱非一致性(选择合适的一致性精度--以牺牲不必要的实时一致性换取分布计算、避免分布事务) 在阐述上面五个基本原则时Randy Shoup始终遵循一个原理:对一个数据系统,下面的三个属性永远只有两个可以同时拥有: 1、数据在任何时候都是一致的(实时一致性) 2、数据是分开保存的(数据是分散的) 3、系统在某些部分(例如硬件故障)发生错误的时候仍能正常工作(容灾容错) 例如,ebay的数据是分散的(因为要做数据分片),系统有容错的需求(因为ebay有很多的服务器,几乎每时每刻都有这台或那台服务器出问题)因此就只能牺牲数据的非必要实时一致性来保证后面两个特性。 由此想到上次产品经理提出的对种子短信进行实时统计的需求,当时经评估建议只做到非实时一致性(最终一致性):在某用户发送种子短信时,只显示对该种子短信统计的局部一致性,即用户自己操作且能感受到这个变化,其它用户的操作不即使反馈到这个用户的视图中,但在下次登录时,该用户可以感受到全局一致性。这种思想应该是与ebay的架构原则是一致的。 作为一个有着大量交易行为的的电子商务网站,ebay不使用分布式事务,对于非分布式的也用的很少,仅仅在拍卖交易这一处使用(这儿要求实时一致性)。后来在淘宝的演讲中,我们得知淘宝也是基本上也不使用事务。 看来英雄所见略同,大型电子商务系统,需要谨慎的使用事务。电子商务系统追求的是最终一致性(eventually consistency)而不是实时一致性(immediately consistency),最终一致性不需要采用数据库的事务的方式来实现,而可以采用类似于现在银行的支付系统的定期对账的方式来实现。ebay认为,就算是银行的金融系统,也是不需要实现实时一致性的。

Linux网络编程(事件驱动模式)

前言前言 事件驱动为广大的程序员所熟悉,其最为人津津乐道的是在图形化界面编程中的应用;事实上,在网络编程中事件驱动也被广泛使用,并大规模部署在高连接数高吞吐量的服务器程序中,如 http 服务器程序、ftp 服务器程序等。相比于传统的网络编程方式,事件驱动能够极大的降低资源占用,增大服务接待能力,并提高网络传输效率。 关于本文提及的服务器模型,搜索网络可以查阅到很多的实现代码,所以,本文将不拘泥于源代码的陈列与分析,而侧重模型的介绍和比较。使用 libev 事件驱动库的服务器模型将给出实现代码。 本文涉及到线程 / 时间图例,只为表明线程在各个 IO 上确实存在阻塞时延,但并不保证时延比例的正确性和 IO 执行先后的正确性;另外,本文所提及到的接口也只是笔者熟悉的 Unix/Linux 接口,并未推荐 Windows 接口,读者可以自行查阅对应的 Windows 接口。 阻塞型的网络编程接口 几乎所有的程序员第一次接触到的网络编程都是从 listen()、send()、recv() 等接口开始的。使用这些接口可以很方便的构建服务器 / 客户机的模型。 我们假设希望建立一个简单的服务器程序,实现向单个客户机提供类似于“一问一答”的内容服务。 图 1. 1. 简单的一问一答的服务器简单的一问一答的服务器简单的一问一答的服务器 / / / 客户机模型客户机模型 客户机模型 我们注意到,大部分的 socket 接口都是阻塞型的。所谓阻塞型接口是指系统调用(一般是 IO 接口)不返回调用结果并让当前线程一直阻塞,只有当该系统调用获得结果或者超时出错时才返回。 实际上,除非特别指定,几乎所有的 IO 接口 ( 包括 socket 接口 ) 都是阻塞型的。这给网络编程带来了一个很大的问题,如在调用 send() 的同时,线程将被阻塞,在此期间,线程将无法执行任何运算或响应任何的网络请求。这给多客户机、多业务逻辑的网络编程带来了挑战。这时,很多程序员可能会选择多线程的方式来解决这个问题。 多线程的服务器程序多线程的服务器程序 应对多客户机的网络应用,最简单的解决方式是在服务器端使用多线程(或多进程)。多线程(或多进程)的目的是让每个连接都拥有独立的线程(或进程),这样任何一个连接的阻塞都不会影响其他的连接。 具体使用多进程还是多线程,并没有一个特定的模式。传统意义上,进程的开销要远远大于线程,所以,如果需要同时为较多的客户机提供服务,则不推荐使用多进程;如果单个

libevent

LibEvent Programmers Manual David F.Skoll Roaring Penguin Software Inc. September30,2002 1Introduction Many UNIX programs are event-driven.They spend most of their time waiting for an event,such as input from a?le descriptor,expiration of a timer,or a signal,and then react to that event. The standard UNIX mechanisms for writing event-driven programs are the se- lect and poll system calls,which wait for input on a set of?le descriptors, optionally with a timeout. While select and poll can be used to write event-driven programs,their calling interface is awkward and their level of abstraction too low.LibEvent is built around select,but provides a more pleasant interface for programmers. LibEvent provides the following mechanisms: ?Events,which trigger under user-speci?ed conditions,such as readabil- ity/writability of a?le descriptor or expiration of a timer. ?Synchronous signal-handling,which is the ability to defer signal-handling to a safe point in the event-handling loop. ?Syncronous child cleanup,which lets you defer calls to wait or waitpid to a safe point in the event-handling loop. 2Overview Figure1indicates the overall?ow of programs using LibEvent. 1.Call Event CreateSelector once to create an Event Selector.This is an object which manages event dispatch. 2.Open?le descriptors as required,and call Event CreateHandler to cre- ate Event Handlers for each descriptor of interest.You can call Event CreateTimerHandler to create timers which are not associated with?le descriptors. 1

构建百万级连接的服务器之理论基础与实现

构建百万级连接的服务器之理论基础与实现 from https://www.360docs.net/doc/ca7115895.html,/blog/archives/740.html#q42013-09-16 著名的C10K 问题提出的时候, 正是2001 年, 到如今12 年后的2013 年, C10K 已经不是问题了, 任何一个普通的程序员, 都能利用手边的语言和库, 轻松地写出C10K 的服务器. 这既得益于软件的进步, 也得益于硬件性能的提高. 现在, 该是考虑C1000K, 也就是百万连接的问题的时候了. 像Twitter, weibo, Facebook 这些网站, 它们的同时在线用户有上千万, 同时又希望消息能接近实时地推送给用户, 这就需要服务器能维持和上千万用户的TCP 网络连接, 虽然可以使用成百上千台服务器来支撑这么多用户, 但如果每台服务器能支持一百万连接(C1000K), 那么只需要十台服务器. 有很多技术声称能解决C1000K 问题, 例如Erlang, Java NIO 等等, 不过, 我们应该首先弄明白, 什么因素限制了 C1000K 问题的解决. 主要是这几点: 操作系统能否支持百万连接?

操作系统维持百万连接需要多少内存? 应用程序维持百万连接需要多少内存? 百万连接的吞吐量是否超过了网络限制? 下面来分别对这几个问题进行分析. 1. 操作系统能否支持百万连接? 对于绝大部分Linux 操作系统, 默认情况下确实不支持 C1000K! 因为操作系统包含最大打开文件数(Max Open Files)限制, 分为系统全局的, 和进程级的限制. 全局限制 在Linux 下执行: cat /proc/sys/fs/file-nr 会打印出类似下面的一行输出: 5100 0 101747 第三个数字101747 就是当前系统的全局最大打开文件数(Max Open Files), 可以看到, 只有10 万, 所以, 在这台服务器上无法支持C1000K. 很多系统的这个数值更小, 为了修改这个数值, 用root 权限修改/etc/sysctl.conf 文件: fs.file-max = 1020000 net.ipv4.ip_conntrack_max = 1020000

libevent

libevent源码深度剖析一 ——序幕 张亮 1 前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少。写这一系列文章的用意在于,一则分享心得;二则对libevent代码和设计思想做系统的、更深层次的分析,写出来,也可供后来者参考。 附带一句:Libevent是用c语言编写的(MS大牛们都偏爱c语言哪),而且几乎是无处不函数指针,学习其源代码也需要相当的c语言基础。 2 Libevent简介 上来当然要先夸奖啦,Libevent 有几个显著的亮点: 事件驱动(event-driven),高性能; 轻量级,专注于网络,不如ACE那么臃肿庞大; 源代码相当精炼、易读; 跨平台,支持Windows、Linux、*BSD和Mac Os; 支持多种I/O多路复用技术,epoll、poll、dev/poll、select和kqueue等; 支持I/O,定时器和信号等事件; 注册事件优先级; Libevent已经被广泛的应用,作为底层的网络库;比如memcached、Vomit、Ny lon、Netchat等等。 Libevent当前的最新稳定版是1.4.13;这也是本文参照的版本。 3 学习的好处 学习libevent有助于提升程序设计功力,除了网络程序设计方面外,Libevent的代码里有很多有用的设计技巧和基础数据结构,比如信息隐藏、函数指针、c语言的多态支持、链表和堆等等,都有助于提升自身的程序功力。 程序设计不止要了解框架,很多细节之处恰恰也是事关整个系统成败的关键。只对libevent 本身的框架大概了解,那或许仅仅是一知半解,不深入代码分析,就难以了解其设计的精巧之处,也就难以为自己所用。 事实上Libevent本身就是一个典型的Reactor模型,理解Reactor模式是理解libevent 的基石;因此下一节将介绍典型的事件驱动设计模式——Reactor模式。 libevent源码深度剖析二 ——Reactor模式

相关主题
相关文档
最新文档