libevent是一个基于事件触发的网络库,memcached底层也是使用libevent库,今天学习下。



总体来说,libevent有下面一些特点和优势:

* 统一数据源, 统一I/O事件,信号和定时器这三种事件;

* 可移植,跨平台支持多种I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等;

* 对并发编程支持,避免竞态条件;

* 高性能,由事件驱动;

* 轻量级,专注于网络;

libevent有下面几大部分组成:

* 事件管理包括各种IO(socket)、定时器、信号等事件,也是libevent应用最广的模块;

* 缓存管理是指evbuffer功能;

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

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

一些资料:

* libevent官网:http://libevent.org/ 

* libevent API:http://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html

* CSDN上剖析得很赞的文章:http://blog.csdn.NET/sparkliang/article/details/4957667

// =============================================================================================

下面写了2个简单的使用例子,一个是定时器,一个是TCP服务器,都只涉及到libevent的事件管理模块。

一、简单定时器:实现程序每秒输出一个“Game Over!”

event_init() => evtimer_set() => event_add() =>event_dispatch()

  1. #include <stdio.h>
  2. #include <iostream>
  3.  
  4. // libevent头文件
  5. #include <event.h>
  6. using namespace std;
  7.  
  8. // 定时事件回调函数
  9. void onTime(int sock, short event, void *arg)
  10. {
  11. cout << "Game Over!" << endl;
  12.  
  13. struct timeval tv;
  14. tv.tv_sec = 1;
  15. tv.tv_usec = 0;
  16. // 重新添加定时事件(定时事件触发后默认自动删除)
  17. event_add((struct event*)arg, &tv);
  18. }
  19.  
  20. int main()
  21. {
  22. // 初始化
  23. event_init();
  24.  
  25. struct event evTime;
  26. // 设置定时事件
  27. evtimer_set(&evTime, onTime, &evTime);
  28.  
  29. struct timeval tv;
  30. tv.tv_sec = 1;
  31. tv.tv_usec = 0;
  32. // 添加定时事件
  33. event_add(&evTime, &tv);
  34.  
  35. // 事件循环
  36. event_dispatch();
  37.  
  38. return 0;
  39. }

编译并执行,编译加 -levent:

gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # mv time.cpp timer.cpp  

gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # g++ -o timer timer.cpp -levent  

gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # ./timer   

Game Over!  

Game Over!  

Game Over!  

Game Over!

二、TCP服务器:实现监听本机8888端口并输出客户端发送过来的信息

event_base_new()=>event_set()=>event_base_set()=>event_add()=>event_base_dispatch()

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <iostream>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8.  
  9. #include <event.h>
  10. using namespace std;
  11.  
  12. // 事件base
  13. struct event_base* base;
  14.  
  15. // 读事件回调函数
  16. void onRead(int iCliFd, short iEvent, void *arg)
  17. {
  18. int iLen;
  19. char buf[1500];
  20.  
  21. iLen = recv(iCliFd, buf, 1500, 0);
  22.  
  23. if (iLen <= 0) {
  24. cout << "Client Close" << endl;
  25.  
  26. // 连接结束(=0)或连接错误(<0),将事件删除并释放内存空间
  27. struct event *pEvRead = (struct event*)arg;
  28. event_del(pEvRead);
  29. delete pEvRead;
  30.  
  31. close(iCliFd);
  32. return;
  33. }
  34.  
  35. buf[iLen] = 0;
  36. cout << "Client Info:" << buf << endl;
  37. }
  38.  
  39. // 连接请求事件回调函数
  40. void onAccept(int iSvrFd, short iEvent, void *arg)
  41. {
  42. int iCliFd;
  43. struct sockaddr_in sCliAddr;
  44.  
  45. socklen_t iSinSize = sizeof(sCliAddr);
  46. iCliFd = accept(iSvrFd, (struct sockaddr*)&sCliAddr, &iSinSize);
  47.  
  48. // 连接注册为新事件 (EV_PERSIST为事件触发后不默认删除)
  49. struct event *pEvRead = new event;
  50. event_set(pEvRead, iCliFd, EV_READ|EV_PERSIST, onRead, pEvRead);
  51. event_base_set(base, pEvRead);
  52. event_add(pEvRead, NULL);
  53. }
  54.  
  55. int main()
  56. {
  57.  
  58. int iSvrFd;
  59. struct sockaddr_in sSvrAddr;
  60.  
  61. memset(&sSvrAddr, 0, sizeof(sSvrAddr));
  62. sSvrAddr.sin_family = AF_INET;
  63. sSvrAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  64. sSvrAddr.sin_port = htons(8888);
  65.  
  66. // 创建tcpSocket(iSvrFd),监听本机8888端口
  67. iSvrFd = socket(AF_INET, SOCK_STREAM, 0);
  68. bind(iSvrFd, (struct sockaddr*)&sSvrAddr, sizeof(sSvrAddr));
  69. listen(iSvrFd, 10);
  70.  
  71. // 初始化base
  72. base = event_base_new();
  73.  
  74. struct event evListen;
  75. // 设置事件
  76. event_set(&evListen, iSvrFd, EV_READ|EV_PERSIST, onAccept, NULL);
  77. // 设置为base事件
  78. event_base_set(base, &evListen);
  79. // 添加事件
  80. event_add(&evListen, NULL);
  81.  
  82. // 事件循环
  83. event_base_dispatch(base);
  84.  
  85. return 0;
  86. }

【VS开发】【数据库开发】libevent简单入门和介绍的更多相关文章

  1. iOS开发数据库篇—SQLite简单介绍

    iOS开发数据库篇—SQLite简单介绍 一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1 ...

  2. iOS开发数据库篇—FMDB简单介绍

    iOS开发数据库篇—FMDB简单介绍 一.简单说明 1.什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 2.FMDB的优点 使用起来 ...

  3. 【转】 iOS开发数据库篇—SQLite简单介绍

    开始学SQLite啦, 原文: http://www.cnblogs.com/wendingding/p/3868893.html iOS开发数据库篇—SQLite简单介绍 一.离线缓存 在项目开发中 ...

  4. 【java开发系列】—— spring简单入门示例

    1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...

  5. 【java开发系列】—— struts2简单入门示例

    前言 最近正好有时间总结一下,过去的知识历程,虽说东西都是入门级的,高手肯定是不屑一顾了,但是对于初次涉猎的小白们,还是可以提供点参考的. struts2其实就是为我们封装了servlet,简化了js ...

  6. 数据库中间件mycat简单入门

    当在项目中mysql数据库成为瓶颈的时候,我们一般会使用主从复制,分库分表的方式来提高数据库的响应速度,比如mysql主从复制,在没有数据库中间件的情况下,我们只能由开发工程师在程序中控制,这对于一个 ...

  7. iOS开发数据库-FMDB

    前言 FMDB是以OC的方式封装了SQLite的C语言API,使用起来更加面向对象,省去了很多麻烦.冗余的C语言代码:对比苹果自带的Core Data框架,更加轻量级和灵活:提供了多线程安全的数据库操 ...

  8. 云开发数据库VS传统数据库丨云开发101

    云开发数据库与传统数据库的不同 在小程序·云开发中,最核心的便是三大组件:数据库.云存储和云函数,从今天开始,我们将开始隔日更的专栏文章,云开发101,在第一周,我们将从最最核心的数据库开始说起. 云 ...

  9. Java中Redis简单入门

    Redis是一个开源的,先进的 key-value 存储可用于构建高性能,可扩展的 Web 应用程序的解决方案. Redis官方网网站是:http://www.redis.io/,如下: Redis ...

随机推荐

  1. [CSS] The :empty Pseudo Selector Gotchas

    The :empty pseudo selector selects empty elements. We can use this to display useful messages instea ...

  2. Laravel Repository Pattern

    Laravel Repository Pattern   The Repository Pattern can be very helpful to you in order to keep your ...

  3. [codevs]线段树练习5

    http://codevs.cn/problem/4927/ #include <iostream> #include <cstdio> #include <algori ...

  4. android studio的安装信息

    默认是会下载sdk等文件的 Preparing "Install Android SDK Tools (revision: 26.1.1)". Downloading https: ...

  5. 粒子群优化算法及其java实现

    憋了两周终于把开题报告憋出来了,再一次证明自己不适合搞学术,哎--,花了点时间把报告中提到的粒子群算法看了看,看了些资料,用java跑起来. 算法简介 粒子群算法最先由Barnhart博士和Kenne ...

  6. 纯CSS画三角形(带边框)

    实例一: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  7. IIS/VS IIS Express 添加MIME映射 svg、woff、woff2、json

    出现问题 页面提示 font-awesome/fonts/fontawesome-webfont.woff2?v=4.3.0 Failed to load resource: the server r ...

  8. Java 内存模型学习笔记

    1.Java类 public class Math { public static final Integer CONSTANT = 666; public int math(){ int a = 1 ...

  9. ? 原创: 铲子哥 搜狗测试 今天 shell编程的时候,往往不会把所有功能都写在一个脚本中,这样不太好维护,需要多个脚本文件协同工作。那么问题来了,在一个脚本中怎么调用其他的脚本呢?有三种方式,分别是fork、source和exec。 1. fork 即通过sh 脚本名进行执行脚本的方式。下面通过一个简单的例子来讲解下它的特性。 创建father.sh,内容如下: #!/bin/bas

    ? 原创: 铲子哥 搜狗测试 今天 shell编程的时候,往往不会把所有功能都写在一个脚本中,这样不太好维护,需要多个脚本文件协同工作.那么问题来了,在一个脚本中怎么调用其他的脚本呢?有三种方式,分别 ...

  10. 【k8s部署kong一】kong k8s 安装 以及可视化管理界面

    官方安装:https://getkong.org/install/kubernetes/ 扩展讲解:https://blog.fleeto.us/post/intro-kong/ 提示:本文是在k8s ...