libevent源码分析

libevent源码分析
libevent源码分析

libevent源码深度剖析

张亮

Email: sparling.liang@https://www.360docs.net/doc/8411565411.html,

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

Email:sparkling.liang@https://www.360docs.net/doc/8411565411.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)

2 集成到事件主循环——通知event_base (29)

4 evsignal_info结构体 (30)

5 注册、注销signal事件 (30)

5 小节 (31)

九集成定时器事件 (32)

1 集成到事件主循环 (32)

2 Timer小根堆 (33)

3 小节 (34)

十支持I/O多路复用技术 (35)

1 统一的关键 (35)

2 设置I/O demultiplex机制 (35)

3 小节 (37)

十一时间管理 (38)

1 初始化检测 (38)

2 时间缓存 (38)

3 时间校正 (40)

4 小节 (41)

十二让libevent支持多线程 (42)

1 错误使用示例 (42)

2 支持多线程的几种模式 (42)

3 例子——memcached (43)

4 小节 (44)

一序幕

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、V omit、Nylon、Netchat 等等。

Libevent当前的最新稳定版是1.4.13;这也是本文参照的版本。

3 学习的好处

学习libevent有助于提升程序设计功力,除了网络程序设计方面外,Libevent的代码里有很多有用的设计技巧和基础数据结构,比如信息隐藏、函数指针、c语言的多态支持、链表和堆等等,都有助于提升自身的程序功力。

程序设计不止要了解框架,很多细节之处恰恰也是事关整个系统成败的关键。只对libevent本身的框架大概了解,那或许仅仅是一知半解,不深入代码分析,就难以了解其设计的精巧之处,也就难以为自己所用。

事实上Libevent本身就是一个典型的Reactor模型,理解Reactor模式是理解libevent 的基石;因此下一节将介绍典型的事件驱动设计模式——Reactor模式。

参考资料:

Libevent: https://www.360docs.net/doc/8411565411.html,/~provos/libevent/

二Reactor模式

前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reactor模式进行必要的介绍,并列出libevnet中的几个重要组件和Reactor的对应关系,在后面的章节中可能还会提到本节介绍的基本概念。

1 Reactor的事件处理机制

首先来回想一下普通函数调用的机制:程序调用某函数?函数执行,程序等待?函数将结果和控制权返回给程序?程序继续处理。

Reactor释义“反应堆”,是一种事件驱动机制。和普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的时间发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。使用Libevent也是想Libevent框架注册相应的事件和回调函数;当这些时间发声时,Libevent会调用这些回调函数处理相应的事件(I/O读写、定时和信号)。

用“好莱坞原则”来形容Reactor再合适不过了:不要打电话给我们,我们会打电话通知你。

举个例子:你去应聘某xx公司,面试结束后。

“普通函数调用机制”公司HR比较懒,不会记你的联系方式,那怎么办呢,你只能面试完后自己打电话去问结果;有没有被录取啊,还是被据了;

“Reactor”公司HR就记下了你的联系方式,结果出来后会主动打电话通知你:有没有被录取啊,还是被据了;你不用自己打电话去问结果,事实上也不能,你没有HR的留联系方式。

2 Reactor模式的优点

Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下的优点:1)响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的;

2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;

3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;

4)可复用性,reactor框架本身与具体事件处理逻辑无关,具有很高的复用性;

3 Reactor模式框架

使用Reactor模型,必备的几个组件:事件源、Reactor框架、多路复用机制和事件处理程序,先来看看Reactor模型的整体框架,接下来再对每个组件做逐一说明。

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——反应器

Reactor,是事件管理的接口,内部使用event demultiplexer注册、注销事件;并运行事件循环,当有事件进入“就绪”状态时,调用注册事件的回调函数处理事件。

对应到libevent中,就是event_base结构体。

一个典型的Reactor声明方式

class Reactor

{

public:

int register_handler(Event_Handler *pHandler, int event);

int remove_handler(Event_Handler *pHandler, int event);

void handle_events(timeval *ptv);

// ...

};

4) Event Handler——事件处理程序

事件处理程序提供了一组接口,每个接口对应了一种类型的事件,供Reactor在相应的事件发生时调用,执行相应的事件处理。通常它会绑定一个有效的句柄。

对应到libevent中,就是event结构体。

下面是两种典型的Event Handler类声明方式,二者互有优缺点。

class Event_Handler

{

public:

virtual void handle_read() = 0;

virtual void handle_write() = 0;

virtual void handle_timeout() = 0;

virtual void handle_close() = 0;

virtual HANDLE get_handle() = 0;

// ...

};

class Event_Handler

{

public:

// events maybe read/write/timeout/close .etc

virtual void handle_events(int events) = 0;

virtual HANDLE get_handle() = 0;

// ...

};

4 Reactor事件处理流程

前面说过Reactor将事件流“逆置”了,那么使用Reactor模式后,事件控制流是什么样子呢?

可以参见下面的序列图。

5 小结

上面讲到了Reactor的基本概念、框架和处理流程,对Reactor有个基本清晰的了解后,再来对比看libevent就会更容易理解了,接下来就正式进入到libevent的代码世界了,加油!

参考资料:

Pattern-Oriented Software Architecture, Patterns for Concurrent and Networked Objects, V olume 2

三基本使用场景和事件流程

1 前言

学习源代码该从哪里入手?我觉得从程序的基本使用场景和代码的整体处理流程入手是个不错的方法,至少从个人的经验上讲,用此方法分析libevent是比较有效的。

2 基本应用场景

基本应用场景也是使用libevnet的基本流程,下面来考虑一个最简单的场景,使用livevent设置定时器,应用程序只需要执行下面几个简单的步骤即可。

1)首先初始化libevent库,并保存返回的指针

struct event_base * base = event_init();

实际上这一步相当于初始化一个Reactor实例;在初始化libevent后,就可以注册事件了。

2)初始化事件event,设置回调函数和关注的事件

evtimer_set(&ev, timer_cb, NULL);

事实上这等价于调用event_set(&ev, -1, 0, timer_cb, NULL);

event_set的函数原型是:

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函数指针的参数;

由于定时事件不需要fd,并且定时事件是根据添加时(event_add)的超时值设定的,因此这里event也不需要设置。

这一步相当于初始化一个event handler,在libevent中事件类型保存在event结构体中。

注意:libevent并不会管理event事件集合,这需要应用程序自行管理;

3)设置event从属的event_base

event_base_set(base, &ev);

这一步相当于指明event要注册到哪个event_base实例上;

4)是正式的添加事件的时候了

event_add(&ev, timeout);

基本信息都已设置完成,只要简单的调用event_add()函数即可完成,其中timeout是定时值;

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

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

event_base_dispatch(base);

3 实例代码

上面例子的程序代码如下所示

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/8411565411.html,_sec = 10; // 10s period

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

evtimer_set(&ev, time_cb, NULL);

event_add(&ev, &tv);

event_base_dispatch(base);

}

4 事件处理流程

当应用程序向libevent注册一个事件后,libevent内部是怎么样进行处理的呢?下面的图就给出了这一基本流程。

1)首先应用程序准备并初始化event,设置好事件类型和回调函数;这对应于前面第步骤2和3;

2)向libevent添加该事件event。对于定时事件,libevent使用一个小根堆管理,key为超时时间;对于Signal和I/O事件,libevent将其放入到等待链表(wait list)中,这是一个双向链表结构;

3)程序调用event_base_dispatch()系列函数进入无限循环,等待事件,以select()函数为例;

每次循环前libevent会检查定时事件的最小超时时间tv,根据tv设置select()的最大等待时间,以便于后面及时处理超时事件;

当select()返回后,首先检查超时事件,然后检查I/O事件;

Libevent将所有的就绪事件,放入到激活链表中;

然后对激活链表中的事件,调用事件的回调函数执行事件处理;

5 小结

本节介绍了libevent的简单实用场景,并旋风般的介绍了libevent的事件处理流程,读者应该对libevent有了基本的印象,下面将会详细介绍libevent的事件管理框架(Reactor模式中的Reactor框架)做详细的介绍,在此之前会对源代码文件做简单的分类。

四 libevent源代码文件组织

1 前言

详细分析源代码之前,如果能对其代码文件的基本结构有个大概的认识和分类,对于代码的分析将是大有裨益的。

2 源代码组织结构

Libevent的源代码虽然都在一层文件夹下面,但是其代码分类还是相当清晰的,主要可分为头文件、内部使用的头文件、辅助功能函数、日志、libevent框架、对系统I/O多路复用机制的封装、信号管理、定时事件管理、缓冲区管理、基本数据结构和基于libevent的两个实用库等几个部分,有些部分可能就是一个源文件。

源代码中的test部分就不在我们关注的范畴了。

1)头文件

主要就是event.h:事件宏定义、接口函数声明,主要结构体event的声明;

2)内部头文件

xxx-internal.h:内部数据结构和函数,对外不可见,以达到信息隐藏的目的;

3)libevent框架

event.c:event整体框架的代码实现;

4)对系统I/O多路复用机制的封装

epoll.c:对epoll的封装;

select.c:对select的封装;

devpoll.c:对dev/poll的封装;

kqueue.c:对kqueue的封装;

5)定时事件管理

min-heap.h:其实就是一个以时间作为key的小根堆结构;

6)信号管理

signal.c:对信号事件的处理;

7)辅助功能函数

evutil.h 和evutil.c:一些辅助功能函数,包括创建socket pair和一些时间操作函数:加、减和比较等。

8)日志

log.h和log.c:log日志函数

9)缓冲区管理

evbuffer.c和buffer.c:libevent对缓冲区的封装;

10)基本数据结构

compat\sys下的两个源文件:queue.h是libevent基本数据结构的实现,包括链表,双向链表,队列等;_libevent_time.h:一些用于时间操作的结构体定义、函数和宏定义;

11)实用网络库

http和evdns:是基于libevent实现的http服务器和异步dns查询库;

3 小结

本节介绍了libevent的组织和分类,下面将会详细介绍libevent的核心部分event结构。

五 libevent的核心:事件event

对事件处理流程有了高层的认识后,本节将详细介绍libevent的核心结构event,以及libevent对event的管理。

1 libevent的核心-event

Libevent是基于事件驱动(event-driven)的,从名字也可以看到event是整个库的核心。event就是Reactor框架中的事件处理程序组件;它提供了函数接口,供Reactor在事件发生时调用,以执行相应的事件处理,通常它会绑定一个有效的句柄。

首先给出event结构体的声明,它位于event.h文件中:

struct event {

TAILQ_ENTRY (event) ev_next;

TAILQ_ENTRY (event) ev_active_next;

TAILQ_ENTRY (event) ev_signal_next;

unsigned int min_heap_idx; /* for managing timeouts */

struct event_base *ev_base;

int ev_fd;

short ev_events;

short ev_ncalls;

short *ev_pncalls; /* Allows deletes in callback */

struct timeval ev_timeout;

int ev_pri; /* smaller numbers are higher priority */

void (*ev_callback)(int, short, void *arg);

void *ev_arg;

int ev_res; /* result passed to event callback */

int ev_flags;

};

下面详细解释一下结构体中各字段的含义。

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

I/O事件: EV_WRITE和EV_READ

定时事件:EV_TIMEOUT

信号:EV_SIGNAL

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

Libevent中的定义为:

#define EV_TIMEOUT0x01

#define EV_READ0x02

#define EV_WRITE0x04

#define EV_SIGNAL0x08

#define EV_PERSIST0x10 /* Persistant event */

可以看出事件类型可以使用“|”运算符进行组合,需要说明的是,信号和I/O事件不能同时

设置;

还可以看出libevent使用event结构体将这3种事件的处理统一起来;

2)ev_next,ev_active_next和ev_signal_next都是双向链表节点指针;它们是libevent对不同事件类型和在不同的时期,对事件的管理时使用到的字段。

libevent使用双向链表保存所有注册的I/O和Signal事件,ev_next就是该I/O事件在链表中的位置;称此链表为“已注册事件链表”;

同样ev_signal_next就是signal事件在signal事件链表中的位置;

ev_active_next:libevent将所有的激活事件放入到链表active list中,然后遍历active list执行调度,ev_active_next就指明了event在active list中的位置;

2)min_heap_idx和ev_timeout,如果是timeout事件,它们是event在小根堆中的索引和超时值,libevent使用小根堆来管理定时事件,这将在后面定时事件处理时专门讲解

3)ev_base该事件所属的反应堆实例,这是一个event_base结构体,下一节将会详细讲解;4)ev_fd,对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号;

5)ev_callback,event的回调函数,被ev_base调用,执行事件处理程序,这是一个函数指针,原型为:

void (*ev_callback)(int fd, short events, void *arg)

其中参数fd对应于ev_fd;events对应于ev_events;arg对应于ev_arg;

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

7)eb_flags:libevent用于标记event信息的字段,表明其当前的状态,可能的值有:

#define EVLIST_TIMEOUT0x01 // event在time堆中

#define EVLIST_INSERTED0x02 // event在已注册事件链表中

#define EVLIST_SIGNAL0x04 // 未见使用

#define EVLIST_ACTIVE0x08 // event在激活链表中

#define EVLIST_INTERNAL0x10 // 内部使用标记

#define EVLIST_INIT 0x80 // event已被初始化

8)ev_ncalls:事件就绪执行时,调用ev_callback的次数,通常为1;

9)ev_pncalls:指针,通常指向ev_ncalls或者为NULL;

10)ev_res:记录了当前激活事件的类型;

2 libevent对event的管理

从event结构体中的3个链表节点指针和一个堆索引出发,大体上也能窥出libevent对event的管理方法了,可以参见下面的示意图。

每次当有事件event转变为就绪状态时,libevent就会把它移入到active event list[priority]中,其中priority是event的优先级;

接着libevent会根据自己的调度策略选择就绪事件,调用其cb_callback()函数执行事件处理;并根据就绪的句柄和事件类型填充cb_callback函数的参数。

3 事件设置的接口函数

要向libevent添加一个事件,需要首先设置event对象,这通过调用libevent提供的函数有:event_set(), event_base_set(), event_priority_set()来完成;下面分别进行讲解。

void event_set(struct event *ev, int fd, short events,

void (*callback)(int, short, void *), void *arg)

1.设置事件ev绑定的文件描述符或者信号,对于定时事件,设为-1即可;

2.设置事件类型,比如EV_READ|EV_PERSIST, EV_WRITE, EV_SIGNAL等;

3.设置事件的回调函数以及参数arg;

4.初始化其它字段,比如缺省的event_base和优先级;

int event_base_set(struct event_base *base, struct event *ev) 设置event ev将要注册到的event_base;

libevent有一个全局event_base指针current_base,默认情况下事件ev 将被注册到current_base上,使用该函数可以指定不同的event_base;

如果一个进程中存在多个libevent实例,则必须要调用该函数为event设置不同的event_base;

int event_priority_set(struct event *ev, int pri)

设置event ev的优先级,没什么可说的,注意的一点就是:当ev正处于就绪状态时,不能设置,返回-1。

4 小结

本节讲述了libevent的核心event结构,以及libevent支持的事件类型和libevent对event的管理模型;接下来将会描述libevent的事件处理框架,以及其中使用的重要的结构体event_base。

六初见事件处理框架

前面已经对libevent的事件处理框架和event结构体做了描述,现在是时候剖析libevent 对事件的详细处理流程了,本节将分析libevent的事件处理框架event_base和libevent注册、删除事件的具体流程,可结合前一节libevent对event的管理。

1 事件处理框架-event_base

回想Reactor模式的几个基本组件,本节讲解的部分对应于Reactor框架组件。在libevent 中,这就表现为event_base结构体,结构体声明如下,它位于event-internal.h文件中:struct event_base {

const struct eventop *evsel;

void *evbase;

int event_count; /* counts number of total events */

int event_count_active; /* counts number of active events */

int event_gotterm; /* Set to terminate loop */

int event_break; /* Set to terminate loop immediately */

/* active event management */

struct event_list **activequeues;

int nactivequeues;

/* signal handling info */

struct evsignal_info sig;

struct event_list eventqueue;

struct timeval event_tv;

struct min_heap timeheap;

struct timeval tv_cache;

};

下面详细解释一下结构体中各字段的含义。

1)evsel和evbase这两个字段的设置可能会让人有些迷惑,这里你可以把evsel和evbase 看作是类和静态函数的关系,比如添加事件时的调用行为:evsel->add(evbase, ev),实际执行操作的是evbase;这相当于class::add(instance, ev),instance就是class的一个对象实例。evsel指向了全局变量static const struct eventop *eventops[]中的一个;

前面也说过,libevent将系统提供的I/O demultiplex机制统一封装成了eventop结构;因此eventops[]包含了select、poll、kequeue和epoll等等其中的若干个全局实例对象。

evbase实际上是一个eventop实例对象;

先来看看eventop结构体,它的成员是一系列的函数指针, 在event-internal.h文件中:

struct eventop {

const char *name;

void *(*init)(struct event_base *); // 初始化

int (*add)(void *, struct event *); // 注册事件

int (*del)(void *, struct event *); // 删除事件

int (*dispatch)(struct event_base *, void *, struct timeval *); // 事件分发

void (*dealloc)(struct event_base *, void *); // 注销,释放资源 /* set if we need to reinitialize the event base */

int need_reinit;

};

也就是说,在libevent中,每种I/O demultiplex机制的实现都必须提供这五个函数接口,来完成自身的初始化、销毁释放;对事件的注册、注销和分发。

比如对于epoll,libevent实现了5个对应的接口函数,并在初始化时并将eventop的5个函数指针指向这5个函数,那么程序就可以使用epoll作为I/O demultiplex机制了,这个在后面会再次提到。

2)activequeues是一个二级指针,前面讲过libevent支持事件优先级,因此你可以把它看作是数组,其中的元素activequeues[priority]是一个链表,链表的每个节点指向一个优先级为priority的就绪事件event。

3)eventqueue,链表,保存了所有的注册事件event的指针。

4)sig是由来管理信号的结构体,将在后面信号处理时专门讲解;

5)timeheap是管理定时事件的小根堆,将在后面定时事件处理时专门讲解;

6)event_tv和tv_cache是libevent用于时间管理的变量,将在后面讲到;

其它各个变量都能因名知意,就不再啰嗦了。

2 创建和初始化event_base

创建一个event_base对象也既是创建了一个新的libevent实例,程序需要通过调用event_init()(内部调用event_base_new函数执行具体操作)函数来创建,该函数同时还对新生成的libevent实例进行了初始化。

该函数首先为event_base实例申请空间,然后初始化timer mini-heap,选择并初始化合适的系统I/O 的demultiplexer机制,初始化各事件链表;

函数还检测了系统的时间设置,为后面的时间管理打下基础。

3 接口函数

前面提到Reactor框架的作用就是提供事件的注册、注销接口;根据系统提供的事件多路分发机制执行事件循环,当有事件进入“就绪”状态时,调用注册事件的回调函数来处理事件。

Libevent中对应的接口函数主要就是:

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

int event_del(struct event *ev);

int event_base_loop(struct event_base *base, int loops);

void event_active(struct event *event, int res, short events);

void event_process_active(struct event_base *base);

本节将按介绍事件注册和删除的代码流程,libevent的事件循环框架将在下一节再具体描述。

对于定时事件,这些函数将调用timer heap管理接口执行插入和删除操作;对于I/O和

社会调查研究方法笔记整理

第二部分社会调查研究方法 要求考生了解社会调查研究的科学过程,了解具体的调查设计与实施方法,了解资料分析的方法及撰写调查报告的要求。 一、社会调查研究的主要过程与内容 社会科学领域常见的研究方式:实验研究、调查研究(社会调查)、实地研究和文献研究。社会调查概念:指的是一种采用自填式问卷或结构式访问的方法,通过直接的询问,从一个取自总体的样本那里收集系统的、量化的资料,并通过对这些资料的统计分 析来认识社会现象及其规律的社会研究方式。 社会调查基本要素:抽样、问卷、统计分析。 社会调查的特征:首先,社会调查在本质上是一种定量的研究方式。其次,社会调查是一种 横剖性的社会研究方式。 社会调查的类型:调查对象范围——普遍调查与抽样调查;收集资料方法——问卷调查(自填问卷与邮寄问卷)和访问调查(当面访问与电话访问);调查目的或作 用——描述性调查和解释性调查;调查性质和应用领域——行政统计调 查、生活状况调查、社会问题调查、市场调查、民意调查和研究性调查。 社会调查的题材:某一人群的社会背景、某一人群的社会行为和活动、某一人群的意见和态度。 普遍调查和抽样调查:抽样调查指从所研究的总体中,按照一定的方式选取一部分个体进行调查,并将在这部分个体中所得到的调查结果推广到总体中去。优点:抽 样调查非常节省时间、人力和财力;十分迅速的获得资料数据;可以比较 详细的收集信息,获得内容丰富的资料;应用范围十分广泛;准确性高。 传统社会调查和现代社会调查: 1、社会调查研究的主要过程与内容:o(╯□╰)o 2、调查研究的主要阶段 a) 确定研究课题并将其系统化(选题阶段) b) 设计研究方案和准备研究工具(准备阶段) c) 资料的收集(实施阶段) d) 资料的处理与分析(分析阶段) e) 结果的解释与报告(总结阶段) 选题阶段的任务:一是选取主题,二是形成研究问题。选择问题阶段受多种因素制约:主观:研究者理论素养、生活阅历、观察角度、研究兴趣;客观:社会环境 等。研究问题选择好坏在一定程度上决定了这个研究工作的成败。 研究设计阶段由两部分组成:道路选择(为了达到研究的目标而进行的研究设计工作,设计研究的思路、策略、方式、方法以及具体技术工具等各个方面);工具准备(对 研究所依赖的测量工具或信息收集工具如问卷、量表、实验手段等等的准备。 问卷的准备和调查对象的选取工作)。 资料收集阶段:主要任务是具体贯彻研究设计中所确定的思路和策略,按照研究设计中所确定的方式、方法和技术进行资料的收集工作。 资料分析阶段:对收集的原始资料进行系统的审核、整理、归类、统计和分析。 得出结果阶段:撰写研究报告,评价研究质量,交流研究成果。

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的错误。

(完整word版)行测总结笔记 学霸笔记 必过

现在开始 资料分析 之所以把资料分析放在第一,是因为本人以前最怕资料分析不难但由于位于最后,时间紧加上数字繁琐,得分率一直很低。而各大论坛上的普遍说法是资料分析分值较高,不可小觑。有一次去面试,有个行测考90分的牛人说他拿到试卷先做资料分析,我也试过,发觉效果并不好,细想来经验因人而议,私以为资料分析还是应该放在最后,只是需要保证平均5分钟一篇的时间余量,胆大心细。 一、基本概念和公式 1、同比增长速度(即同比增长率)=(本期数-去年同期数)/去年同期数x100% =本期数/去年同期数-1 显然后一种快得多 环比增长速度(即环比增长率)=(本期数-上期数)/上期数=本期数/上期数-1 2、百分数、百分比(略) 3、比重(略) 4、倍数和翻番 翻番是指数量的加倍,翻番的数量以2^n次变化 5、平均数(略) 6、年均增长率 如果第一年的数据为A,第n+1年为B 二、下面重点讲一下资料分析速算技巧 1、a=b÷(1+x%)≈b×(1-x%)结果会比正确答案略小,记住是略小,如果看到有个选项比 你用这种方法算出来的结果略大,那么就可以选;比它小的结果不管多接近一律排除; x越小越精确 a=b÷(1-x%)≈bX(1+x%)结果会比正确答案略小,x越小越精确 特别注意: ⑴当选项差距比较大时,推荐使用该方法,当差距比较小时,需验证 ⑵增长率或者负增长率大于10%,不适用此方法 2、分子分母比较法 ⑴分子大分母小的分数大于分子小分母大的分数 ⑵差分法★ 若其中一个分数的分子和分母都大于另外一个分数的分子和分母,且大一点点时,差分法非常适用。 例:2008年产猪6584头,2009年产猪8613头,2010年产猪10624头,问2009与2010哪一年的增长率高 答:2009增长率8613/6584-1 ,2010增长率10624/8613-1,-1不用看,利用差分法

libevent

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

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

Memcached源码剖析笔记

Memcached 源码剖析笔记 Xguru Memcached是一个自由、源码开放、高性能、分布式 内存对象缓存系统,目的在于通过减轻数据库负载来使 动态Web应用程序提速。

目录 1.背景 (3) 2.memcached的安装 (4) 3.memcached的配置 (5) 4.memcached的使用 (6) 4.1.存储命令 (7) 4.2.读取命令 (8) 4.3.删除命令 (8) 4.4.高级命令 (9) 4.5.其他命令 (10) 5.Memcached内部工作机制 (11) 5.1.Memcached基本的数据结构 (11) 5.2.基本设计概念和处理流程 (12) 5.3.内部Hash机制 (15) 5.3.1.Hash函数及冲突解决 (15) 5.3.2.HashTable主要函数 (15) 5.4.slab内存处理机制 (17) 5.4.1.slab主要函数 (17) 5.4.2.slab机制中所采用的LRU算法 (19) 5.5.控制item各种函数 (20) 5.6.守护进程机制 (22) 5.7.Socket处理机制 (23) 1

5.7.1.Unix域协议 (23) 5.7.2.TCP/UDP协议 (24) 5.8.多线程处理机制 (25) 5.9.事件处理机制 (25) 6.未完善之处 (27) 7.参考文献 (28) 2

1.背景 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。 Memcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。 Memcached是一个在内存中对任意的数据(比如字符串,对象等)所使用的key-value 存储。数据可以来自数据库调用,API调用,或者页面渲染的结果。 Memcached设计理念就是小而强大,它简单的设计促进了快速部署、易于开发,并解决面对大规模的数据缓存的许多难题。所开放的API能用于大部分流行的程序语言 3

资料分析报告笔记整理好

资料分析笔记整理 一.资料分析基础概念与解题技巧 1.资料分析核心运算公式 2.资料分析常用基本概念 3.资料分析速算技巧 二.资料分析高频高点梳理 1.ABR类问题 2.比重类问题 资料分析基础概念与解题技巧 一、基期、本期 基期,表示的是在比较两个时期的变化时,用来做比较值(基准值)的时期,该时期的数值通常作为计算过程中的除数或者减数; 本期,相对于基期而言,是当前所处的时期,该时期的数值通常作为计算过程中的被除数或者被减数。 【注】和谁相比,谁做基期。 二、增长量、增长率(增长速度、增长幅度) 增长量,表示的是本期与基期之间的绝对差异,是一绝对值。 增长率,表示的是末期与基期之间的相对差异,是一相对值。 增长率=增长速度(增速)=增长幅度(增幅) 【注】在一些“最值”比较题的题干表述中,经常出现“增加(长)最多”和“增加(长)最快”,我们需要注意,前者比较的是增长量,而后者则比较的是增长率。 三、同比、环比 同比和环比均表示的是两个时期的变化情况,但是这两个概念比较的基期不同。同比,指的是本期发展水平与历史同期的发展水平的变化情况,其基期对应的是历史同期。 环比,指的是本期发展水平与上个统计周期的发展水平的变化情况,其基期对应的是上个统计周期。 【注】环比常出现在月份、季度相关问题。 四、公式运用与练习 资料分析的考察离不开对于两个时期的数值的比较,由此得出四个概念,

即基期(A),本期(B),增长率(R),增长量(X)。 增长量=基期量*增长率=本期量-基期量=本期量-本期量/1+增长率 增长率=增长量/基期量=(本期量-基期量)/基期量=本期量/基期量-1 本期=基期+增长量=基期+基期*增长率=基期*(1+增长率) 基期=本期-增长量=本期/1+增长率 【习题演练】 【例一】2012年1-3月,全国进出口总值为8593.7亿美元,同比增长7.3%,其中:出口4300.2亿美元,增长7.6%;进口4293.6亿美元,增长6.9%。3月当月,全国进出口总值为3259.7亿美元,同比增加216亿美元,其中:出口1656.6亿美元,增长135.4亿美元;进口1603.1亿美元,增长5.3%。 1、2011年一季度,全国进出口总值约为多少? 2、2012年一季度,全国出口额同比增长多少? 3、2011年三月份,全国进出口总值约为多少? 4、2012年三月份,全国出口总值同比增速约为多少? 【注】进出口相关问题,为资料分析中的一个易错点,注意题目中进出口、进口、出口的表述,注意进出口量与进出口额的不同,理解顺差、逆差的含义 出口-进口=顺差,反之则是逆差 2、资料分析常用基本概念 一、百分数、百分点 百分数,表示的是将相比较的基期的数值抽象为100,然后计算出来的数值,用“%”表示,一般通过数值相除得到,在资料分析题目常用在以下情况:(1)部分在整体中所占的比重;(2)表示某个指标的增长率或者减少率。 百分点,表示的是增长率、比例等以百分数表示的指标的变化情况,一般通过百分数相减得到,在资料分析题目常用在以下情况:(1)两个增长率、比例等以百分数表示的数值的差值;(2)在A拉动B增长几个百分点,这样的表述中。【例1】2010年,某省地区生产总值达到6835.7亿元,比去年同期增长14.9%。其中,第一产业增加值为483.5亿元,比去年同期增长25.8%,第二产业增加值为2985.6亿元,同比增长12.5%。 1、2010年,该省第一产业增加值占地区生产总值的比重为()。A.12.63% B.12.63个百分点 C.7.07% D.7.07个百分点 2、2010年,该省第一产业增加值同比增速比第二产业增加值增速高()。A.13.3% B.13.3个百分点 C.14.3% D.14.3个百分点 二、倍数、翻番 倍数,指将对比的基数抽象为1,从而计算出的数值。 翻番,指数量的加倍,如:如果某指标是原来的2倍,则意味着翻了一番,是原来的4倍,则意味着翻了两番,依此类推。所用的公式为:末期/基期=2n,即翻了n番。 【注】注意“超过N倍”“是xx的N倍”两种说法的区别。超过N倍,说明是基数的N+1倍。

公务员考试行测资料分析状元笔记

2017年公务员考试行测资料分析状元笔记通用阅读——上看标题,下看注释,中间看时间,单位(重点) 1文字性材料——难的是阅读(结构阅读是重点) 文字性材料阅读结构和中心 结构几段落——总分和并列—并列部分找中心词(圈点标点,括号标结构,圈标中心词)无结构小段,就仔细阅读,创造结构(圈点标点,标点暗示结构,括号标结构,圈标中心词)无结构大段,就直接读题—找两个关键词——区分性(平均气温),明显性(符号数字字母,例如括号,摄氏度,顿号之类的)——2007年底比2007年更合适 多个题目涉及同一个关键词的,可以一起做 2表格型材料——难的是计算 阅读横标目和纵标目 分清合计和项目和地区 3图形型材料——难的是理解 饼状图——看周围类别名称(包括大小的排名要心中有印象) 柱状趋势图——看横轴和纵轴(要注意两个纵轴的分别对应柱状和点) 柱状分两种:一种是绝对值(高低差异),一种是比例(高低相同,柱状分几个部分) 4统计术语(不是重点) 增长率是属于后一年(所以第一年的增长率是算不出来的) 前一年的总量=后一年除以(1+增长率)后一年除以(1-增长率) 增长率的对比(很容易会出隔两年的总量,倒推2次):增长率增长或降低了5个百分点(直接加减) 乘以2看成除以5 乘以5看成除以2 乘以25看成除以4 除以125看成乘以8 同比是与上一年的同一期相比较 环比是挨着的相同时间段相比较 同比和环比:如果有注释按注释为准 今年5月份环比=今年4月份 今年5月份同比=去年5月份 5统计性数据的要素——时间和单位(重点) 1时间表述(陷阱)——对时间很敏感 1.计算的年份不一样 2.计算的时间段不一样 2单位表述(陷阱)——对单位很敏感 1.饼状图有单位,就不是百分比 相比较的数据的单位不一样(注意是百分号还是千分号。年利率往往用百分,月利率用千分之) 2.计算的单位不一样 下列选项一定正确和一定错误的题目是最难的,可以放在最后做。

资料分析笔记整理样本

资料分析笔记整顿 一.资料分析基本概念与解题技巧 1.资料分析核心运算公式 2.资料分析惯用基本概念 3.资料分析速算技巧 二.资料分析高频高点梳理 1.ABR类问题 2.比重类问题 资料分析基本概念与解题技巧 一、基期、本期 基期,表达是在比较两个时期变化时,用来做比较值(基准值)时期,该时期数值普通作为计算过程中除数或者减数; 本期,相对于基期而言,是当前所处时期,该时期数值普通作为计算过程中被除数或者被减数。 【注】和谁相比,谁做基期。 二、增长量、增长率(增长速度、增长幅度) 增长量,表达是本期与基期之间绝对差别,是一绝对值。 增长率,表达是末期与基期之间相对差别,是一相对值。 增长率=增长速度(增速)=增长幅度(增幅) 【注】在某些“最值”比较题题干表述中,经常浮现“增长(长)最多”和“增长(长)最快”,咱们需要注意,前者比较是增长量,而后者则比较是增长率。 三、同比、环比 同比和环比均表达是两个时期变化状况,但是这两个概念比较基期不同。 同比,指是本期发展水平与历史同期发展水平变化状况,其基期相应是历史同期。

环比,指是本期发展水平与上个记录周期发展水平变化状况,其基期相应是上个记录周期。 【注】环比常出当前月份、季度有关问题。 四、公式运用与练习 资料分析考察离不开对于两个时期数值比较,由此得出四个概念, 即基期(A),本期(B),增长率(R),增长量(X)。 增长量=基期量*增长率=本期量-基期量=本期量-本期量/1+增长率 增长率=增长量/基期量=(本期量-基期量)/基期量=本期量/基期量-1 本期=基期+增长量=基期+基期*增长率=基期*(1+增长率) 基期=本期-增长量=本期/1+增长率 【习题演习】 【例一】1-3月,全国进出口总值为8593.7亿美元,同比增长7.3%,其中:出口4300.2亿美元,增长7.6%;进口4293.6亿美元,增长6.9%。3月当月,全国进出口总值为3259.7亿美元,同比增长216亿美元,其中:出口1656.6亿美元,增长135.4亿美元;进口1603.1亿美元,增长5.3%。 1、一季度,全国进出口总值约为多少? 2、一季度,全国出口额同比增长多少? 3、三月份,全国进出口总值约为多少? 4、三月份,全国出口总值同比增速约为多少? 【注】进出口有关问题,为资料分析中一种易错点,注意题目中进出口、进口、出口表述,注意进出口量与进出口额不同,理解顺差、逆差含义 出口-进口=顺差,反之则是逆差 2、资料分析惯用基本概念 一、百分数、百分点 百分数,表达是将相比较基期数值抽象为100,然后计算出来数值,用“%”表

基于Libevent的HTTP Server

基于Libevent的HTTP Server 简单的Http Server 使用Libevent内置的http相关接口,可以很容易的构建一个Http Server,一个简单的Http Server如下: #include #include #include #include #include #include int init_win_socket() { WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2) , &wsaData) != 0) { return -1; } return0; } void generic_handler(struct evhttp_request *req, void *arg) { struct evbuffer *buf = evbuffer_new(); if(!buf) { puts("failed to create response buffer \n"); return; } evbuffer_add_printf(buf, "Server Responsed. Requested: %s\n", evhttp_request_get_uri(req)); evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); } int main(int argc, char* argv[]) { #ifdef WIN32 init_win_socket();

粉笔资料分析听课笔记(整理版)

粉笔资料分析听课笔记(整理版)一、常用分数、百分数、平方 1 3=33.3% 1 4=25% 1 5=20% 1 6=16.7% 1 7=14.3% 1 8=12.5% 1 9=11.1% 1 10=10% 1 11=9.1% 1 12=8.3% 1 13=7.7% 1 14=7.1% 1 15=6.7% 1 16=6.3% 1 1.5=66.7% 1 2.25=44% 1 2.5=40% 1 3.5=28.6% 1 4.5=22% 1 5.5=18.2% 1 6.5=15.4% 1 7.5=13.3% 1 8.5=11.8% 1 9.5=10.5% 1 10.5=9.5% 1 11.5=8.7% 1 12.5=7.8% 1 13.5=7.4% 1 14.5=6.9% 1 15.5=6.5% 1 16.5=6.1% 22=2 32=942=1652=2562=3672=4982=64 92=81 102=100112= 121122=144132=169 142=196152=225 162=256 172=289182=324192=361202=400212=441 222=484232=529 242=576252 =625 262=676272=729 282=784292=841 二、截位直除速算法 三、其他速算技巧 1、一个数×1.5,等于这个数本身加上这个数的一半。 2、一个数×1.1等于这个数错位相加. 3、一个数×0.9等于这个数错位相减. 4、一个数÷5,等于这个数乘以2,乘积小数点向前移1位。

5、一个数÷25,等于这个数乘以4,乘积小数点向前移2位。 6、一个数÷125,等于这个数乘以8,乘积小数点向前移3位。 7、比较类:①分母相同,分子大的大;分子相同,分母小的大。 ②分子大分母小>分子小分母大。③当分母大分子大,分母小分子小时,看分母与分母的倍数,分子与分子的倍数,谁倍数大听谁的,谁小统统看为1,再比较。 四、统计术语 1、基期:相对于今年来说,去年的就是基期。 2、现期:相对于去年来说,今年的就是现期。 3、基期量:相对于今年来说,去年的量就是基期量。 4、现期量:相对于去年来说,今年的量就是基期量。 5、增长量:现期量和基期量的差值,就是增长量。 6、增长率:增长量与基期量的比值,就是增长率。 7、倍数:A 是B 的多少倍;A 为B 的多少倍,等于增长率加1。 辨析:A 比B 增长了500%,那么就是A 比B 增长(多)5倍,A 是B 的6倍。 8、比重:A 占B 的比重,A 占B 为多少;都等于 A B 。 A 占B 的比重比C 的比重为:A B - C B 。 9、平均数:在一组数据中所有数据之和再除以数据的个数。 10、同比:同比看年,今年与去年同期比。 11、环比:环比看尾,“年”“月”“日”等。

深度剖析KMP

深度剖析KMP,让你认识真正的Next KMP算法,想必大家都不陌生,它是求串匹配问题的一个经典算法(当然如果你要理解成放电影的KMP,请退出本页面直接登录各大电影网站,谢谢),我想很多人对它的理解仅限于此,知道KMP能经过预处理然后实现O(N*M)的效率,比brute force(暴力算法)更优秀等等,其实KMP算法中的Next函数,功能十分强大,其能力绝对不仅仅限于模式串匹配,它并不是KMP的附属品,其实它还有更多不为人知的神秘功能^_^ 先来看一个Next函数的典型应用,也就是模式串匹配,这个相信大家都很熟悉了: POJ 3461 Oulipo——很典型的模式串匹配问题,求模式串在目标串中出现的次数。 #include #include #include #include #include using namespace std; #define MAX 1000001 char t[MAX]; char s[MAX]; int next[MAX]; inline void calnext(char s[],int next[]) { int i; int j; int len=strlen(s); next[0]=-1; j=-1; for(i=1;i=0&&s[i]!=s[j+1]) j=next[j]; if(s[j+1]==s[i])//上一个循环可能因为j=-1而不做,此时不能知道s[i]与s[j+1]的关系。故此需要此条件。 j++; next[i]=j; } } int KMP(char t[],char s[]) { int ans=0; int lent=strlen(t); int lens=strlen(s); if(lent

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模式

httpsqs源码分析

Httpsqs是一个消息队列服务器,他调用的接口是tokyocabinet,tokyocabinet是一个数据库的持久化库,保存。 Httpsqs1.6 设计到的第3方库: Libevent: 这个不用介绍了 Tokyocabinet:数据库的持久化库 Httpsqs1.6 采用的是单线程通信,通信的采用的是libevent,因为Tokyocabinet的处理速度很快,在业务处理方面不存在阻塞的问题,所以采用单线程。 整体流程: httpsqs_handler 图1 整体流程

httpsqs_handler的处理流程 图 2 上面的处理流程只列出了put,get 2种命令,其实还有其他的命令,处理很put,get差不多 上面2个图,就是httpsqs的大概的流程。 Tokyocabinet 是一个的持久化数据库,怎么能做成队列呢? 下面以一个队列来举例说明: 假如我们要往LogQueue队列插入数据,LogQueue并不是一个Key值,他的Key值是LogQueue:1,LogQueue:2,LogQueue:3 ………….. LogQueue:10000…….,哪这个1,2,3…………….10000是怎么控制的呢,这又设计到另为2个Key值,LogQueue:get, LogQueue:put。具体操作见源码。 上面是httpsqs1.6的大概分析。 目前在项目中遇到的问题: 1往一个队列中插入数据时,插入数据OK,但取数据的时候,数据为空原因:初步认为是调用tcbdbput2失败了,httpsqs1.6在调用这个接口时没有返回 值,httpsqs1.6本身根本就不知道是否保存成功。 根据以上,改了一个httpsqs2.6的版本 1 httpsqs1.6采用的B+树的方式(见Tokyocabinet代码),把httpsqs1.6中所有的tcb

粉笔资料分析听课笔记(整理版)

粉笔资料分析听课笔记(整理版) 一、常用分数、百分数、平方 13 =33.3% 14 =25% 15 =20% 16 =16.7% 17 =14.3% 1 8 =12.5% 19 =11.1% 110 =10% 111 =9.1% 112 =8.3% 113 =7.7% 1 14 =7.1% 115 =6.7% 1 16 =6.3% 11.5 =66.7% 12.25 =44% 12.5 =40% 13.5 =28.6% 14.5 =22% 15.5 =18.2% 16.5 =15.4% 17.5 =13.3% 18.5 =11.8% 19.5 =10.5% 110.5 =9.5% 111.5 =8.7% 112.5 =7.8% 113.5 =7.4% 114.5 =6.9% 115.5 =6.5% 116.5 =6.1% 22=2 32=9 42=16 52=25 62=36 72=49 82=64 92=81 102=100 112= 121 122=144 132=169 142=196 152=225 162=256 172=289 182=324 192=361 202=400 212=441 222=484 232=529 242=576 252 =625 262=676 272=729 282=784 292=841 二、截位直除速算法

三、其他速算技巧 1、一个数×1.5,等于这个数本身加上这个数的一半。 2、一个数×1.1等于这个数错位相加. 3、一个数×0.9等于这个数错位相减. 4、一个数÷5,等于这个数乘以2,乘积小数点向前移1位。 5、一个数÷25,等于这个数乘以4,乘积小数点向前移2位。 6、一个数÷125,等于这个数乘以8,乘积小数点向前移3位。 7、比较类:①分母相同,分子大的大;分子相同,分母小的大。 ②分子大分母小>分子小分母大。③当分母大分子大,分母小分子小时,看分母与分母的倍数,分子与分子的倍数,谁倍数大听谁的,谁小统统看为1,再比较。 四、统计术语 1、基期:相对于今年来说,去年的就是基期。 2、现期:相对于去年来说,今年的就是现期。 3、基期量:相对于今年来说,去年的量就是基期量。 4、现期量:相对于去年来说,今年的量就是基期量。 5、增长量:现期量和基期量的差值,就是增长量。 6、增长率:增长量与基期量的比值,就是增长率。 7、倍数:A是B的多少倍;A为B的多少倍,等于增长率加1。 辨析:A比B增长了500%,那么就是A比B增长(多)5倍,A是B的6倍。

粉笔资料分析听课笔记(整理版)教学文案

粉笔资料分析听课笔记(整理版)

粉笔资料分析听课笔记(整理版) 一、常用分数、百分数、平方 13 =33.3% 14 =25% 15 =20% 16 =16.7% 17 =14.3% 18 =12.5% 19 =11.1% 110 =10% 111 =9.1% 112 =8.3% 113 =7.7% 114 =7.1% 115 =6.7% 1 16 =6.3% 11.5 =66.7% 12.25 =44% 12.5 =40% 13.5 =28.6% 14.5 =22% 1 5.5 =18.2% 1 6.5 =15.4% 1 7.5 =13.3% 1 8.5 =11.8% 1 9.5 =10.5% 110.5 =9.5% 1 11.5 =8.7% 112.5 =7.8% 113.5 =7.4% 114.5 =6.9% 115.5 =6.5% 1 16.5 =6.1% 22=2 32=9 42=16 52=25 62=36 72=49 82=64 92=81 102=100 112= 121 122=144 132=169 142=196 152=225 162=256 172=289 182=324 192=361 202=400 212=441 222=484 232=529 242=576 252 =625 262=676 272=729 282=784 292=841 二、截位直除速算法

三、其他速算技巧 1、一个数×1.5,等于这个数本身加上这个数的一半。 2、一个数×1.1等于这个数错位相加. 3、一个数×0.9等于这个数错位相减. 4、一个数÷5,等于这个数乘以2,乘积小数点向前移1位。 5、一个数÷25,等于这个数乘以4,乘积小数点向前移2位。 6、一个数÷125,等于这个数乘以8,乘积小数点向前移3位。 7、比较类:①分母相同,分子大的大;分子相同,分母小的大。 ②分子大分母小>分子小分母大。③当分母大分子大,分母小分子小时,看分母与分母的倍数,分子与分子的倍数,谁倍数大听谁的,谁小统统看为1,再比较。 四、统计术语 1、基期:相对于今年来说,去年的就是基期。 2、现期:相对于去年来说,今年的就是现期。 3、基期量:相对于今年来说,去年的量就是基期量。 4、现期量:相对于去年来说,今年的量就是基期量。 5、增长量:现期量和基期量的差值,就是增长量。 6、增长率:增长量与基期量的比值,就是增长率。 7、倍数:A是B的多少倍;A为B的多少倍,等于增长率加1。 辨析:A比B增长了500%,那么就是A比B增长(多)5倍,A 是B的6倍。 8、比重:A占B的比重,A占B为多少;都等于A B 。

粉笔资料分析听课笔记(整理版)

粉笔资料分析听课笔记(整理版) 一、常用分数、百分数、平方 1 3 =33.3% 1 4 =25% 1 5 =20% 1 6 =16.7% 1 7 =14.3% 1 8 =12.5% 1 9 =11.1% 1 10 =10% 1 11 =9.1% 1 12 =8.3% 1 13 =7.7% 1 14 =7.1% 1 15 =6.7% 1 16 =6.3% 1 1.5 =66.7% 1 2.25 =44% 1 2.5 =40% 1 3.5 =28.6% 1 4.5 =22% 1 5.5 =18.2% 1 6.5 =15.4% 1 7.5 =13.3% 1 8.5 =11.8% 1 9.5 =10.5% 1 10.5 =9.5% 1 11.5 =8.7% 1 12.5 =7.8% 1 13.5 =7.4% 1 14.5 =6.9% 1 15.5 =6.5% 1 16.5 =6.1% 22=2 32=9 42=16 52=25 62=36 72=49 82=64 92=81 102=100 112= 121 122=144 132=169 142=196 152=225 162=256 172=289 182=324 192=361 202=400 212=441 222=484 232=529 242=576 252 =625 262=676 272=729 282=784 292=841 二、截位直除速算法 逍遥龙舞公考笔记1

三、其他速算技巧 1、一个数×1.5,等于这个数本身加上这个数的一半。 2、一个数×1.1 等于这个数错位相加. 3、一个数×0.9 等于这个数错位相减. 4、一个数÷5,等于这个数乘以2,乘积小数点向前移 1 位。 5、一个数÷25,等于这个数乘以4,乘积小数点向前移 2 位。 6、一个数÷125,等于这个数乘以8,乘积小数点向前移 3 位。 7、比较类:①分母相同,分子大的大;分子相同,分母小的大。 ②分子大分母小>分子小分母大。③当分母大分子大,分母小分子小 时,看分母与分母的倍数,分子与分子的倍数,谁倍数大听谁的,谁 小统统看为1,再比较。 四、统计术语 1、基期:相对于今年来说,去年的就是基期。 2、现期:相对于去年来说,今年的就是现期。 3、基期量:相对于今年来说,去年的量就是基期量。 4、现期量:相对于去年来说,今年的量就是基期量。 5、增长量:现期量和基期量的差值,就是增长量。 6、增长率:增长量与基期量的比值,就是增长率。 7、倍数:A是B的多少倍;A为B 的多少倍,等于增长率加1。 辨析:A比B增长了500%,那么就是A比B增长(多)5 倍,A是B的6 倍。 逍遥龙舞公考笔记2

资料分析知识点(整理版)

资料分析 第一节 增长 【例1】2012年国家外汇储备33116亿美元,2011年国家外汇储备31812亿美元。 {求增长量}○12012年国家外汇储备比上年增加了多少亿美元? {求增长率}○22012年国家外汇储备比上年增加了百分之几? 解析:○133116-31812;○2%10013181233116%100318123181233116??? ? ??-=?- 【例2】2012年2月因低温冷冻天气造成直接经济损失61亿元,比1月份减少27亿元,比2011年2月减少21亿元。2012年2月的损失比1月减少了百分之几?比上年2月减少了百分之几? 解析:○1%100276127?+;○ 2%100216121?+ 【例3】2012年社会消费品零售总额183996亿元,2012年社会消费品零售总额比2011年增长了14.3%。

{求基期量}①2011年社会消费品零售总额为多少亿元?(% 3.141183996+) {求现期量}②按此增速,到2013年社会消费品零售总额预计达到多少亿元?(()%3.141183996+?) {求现期量}③2012年社会消费品零售总额比2011年多多少亿元?(%3.14% 3.141183996?+) 第二节 同比增长与环比增长 1.同比是强调相同时间特性下的两个量之间的比较;而环比则是强调时间顺延下的两个量之间的比较。 2、有关公式

第三节 年均增长与年均增长率 时间差 首段时间该指标量末段时间该指标量平均增长量-= 如果第m 年数据指标为A ,第n 年数据指标为B ,那么这几年 年均增长量=m n A B -- ★年均增长量是指标在一段时间内平均每年的增长幅度。如果第m 年数据指标为A ,第n 年数据指标为B ,这几年的年均增长率为x ,且1-=-m n A B x ① (1)已知第m 年数据指标为A ,年均增长率为x ,求第n 年数据指标B 。 [] 略大于该值)B x m n A x A B m n ()(1)1(-+?≈+?=-②(前提:x <10%) (2)已知第m 年数据指标为A ,第n 年数据指标为B ,求年均增长率。 第n 年相对于第m 年的增长率为x ,1-=A B x 根据①式得()A B x m n =+-1,则有()11+=+-x x m n 根据二项式展开得()()()2 2 1x m n m n x m n x ---+-≈③,()实际值1-

华图钻石班笔记之资料分析

资料分析——先读题后题目 通用阅读——上看标题,下看注释,中间看时间,单位(重点) 1文字性材料——难的是阅读(结构阅读是重点) 文字性材料阅读结构和中心 结构几段落——总分和并列—并列部分找中心词(圈点标点,括号标结构,圈标中心词)无结构小段,就仔细阅读,创造结构(圈点标点,标点暗示结构,括号标结构,圈标中心词)无结构大段,就直接读题—找两个关键词——区分性(平均气温),明显性(符号数字字母,例如括号,摄氏度,顿号之类的)——2007年底比2007年更合适 多个题目涉及同一个关键词的,可以一起做 2表格型材料——难的是计算 阅读横标目和纵标目 分清合计和项目和地区 3图形型材料——难的是理解 饼状图——看周围类别名称(包括大小的排名要心中有印象) 柱状趋势图——看横轴和纵轴(要注意两个纵轴的分别对应柱状和点) 柱状分两种:一种是绝对值(高低差异),一种是比例(高低相同,柱状分几个部分) 4统计术语(不是重点) 增长率是属于后一年(所以第一年的增长率是算不出来的) 前一年的总量=后一年除以(1+增长率)后一年除以(1-增长率) 增长率的对比(很容易会出隔两年的总量,倒推2次):增长率增长或降低了5个百分点(直接加减) 乘以2看成除以5 乘以5看成除以2 乘以25看成除以4 除以125看成乘以8 同比是与上一年的同一期相比较 环比是挨着的相同时间段相比较 同比和环比:如果有注释按注释为准 今年5月份环比=今年4月份 今年5月份同比=去年5月份 5统计性数据的要素——时间和单位(重点) 1时间表述(陷阱)——对时间很敏感 1.计算的年份不一样 2.计算的时间段不一样 2单位表述(陷阱)——对单位很敏感 1.饼状图有单位,就不是百分比 相比较的数据的单位不一样(注意是百分号还是千分号。年利率往往用百分,月利率用千分之) 2.计算的单位不一样 下列选项一定正确和一定错误的题目是最难的,可以放在最后做。 中国有没有到96%,言下之意是其他有没有到4%

相关文档
最新文档