中文JAVA技术平等自由协作创造

Java专题文章博客和开源

常用链接

统计

最新评论

libevent库定时器的使用

  libevent库定时器的使用

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #define RELOAD_TIMEOUT 5

  #define DEFAULT_FILE "sample.html"

  char *filedata;

  time_t lasttime = 0;

  char filename[80];

  int counter = 0;

  void read_file()

  {

  int size = 0;

  char *data;

  struct stat buf;

  stat(filename,&buf);

  if (buf.st_mtime > lasttime)

  {

  if (counter++)

  fprintf(stderr,"Reloading file: %s",filename);

  else

  fprintf(stderr,"Loading file: %s",filename);

  FILE *f = fopen(filename, "rb");

  if (f == NULL)

  {

  fprintf(stderr,"Couldn't open file\n");

  exit(1);

  }

  fseek(f, 0, SEEK_END);

  size = ftell(f);

  fseek(f, 0, SEEK_SET);

  data = (char *)malloc(size+1);

  fread(data, sizeof(char), size, f);

  filedata = (char *)malloc(size+1);

  strcpy(filedata,data);

  fclose(f);

  fprintf(stderr," (%d bytes)\n",size);

  lasttime = buf.st_mtime;

  }

  }

  void load_file()

  {

  struct event *loadfile_event;

  struct timeval tv;

  read_file();

  tv.tv_sec = RELOAD_TIMEOUT;

  tv.tv_usec = 0;

  loadfile_event = malloc(sizeof(struct event));

  evtimer_set(loadfile_event,

  load_file,

  loadfile_event);

  evtimer_add(loadfile_event,

  &tv);

  }

  void generic_request_handler(struct evhttp_request *req, void *arg)

  {

  struct evbuffer *evb = evbuffer_new();

  evbuffer_add_printf(evb, "%s",filedata);

  evhttp_send_reply(req, HTTP_OK, "Client", evb);

  evbuffer_free(evb);

  }

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

  {

  short http_port = 8081;

  char *http_addr = "192.168.0.22";

  struct evhttp *http_server = NULL;

  if (argc > 1)

  {

  strcpy(filename,argv[1]);

  printf("Using %s\n",filename);

  }

  else

  {

  strcpy(filename,DEFAULT_FILE);

  }

  event_init();

  load_file();

  http_server = evhttp_start(http_addr, http_port);

  evhttp_set_gencb(http_server, generic_request_handler, NULL);

  fprintf(stderr, "Server started on port %d\n", http_port);

  event_dispatch();

  }

  这个服务器的基本原理与前面的示例相同。首先,脚本设置一个 HTTP 服务器,它只响应对基本 URL 主机/端口组合的请求(不处理请求 URI)。第一步是装载文件 (read_file())。在装载最初的文件时和在计时器触发回调时都使用此函数。

  read_file() 函数使用 stat() 函数调用检查文件的修改时间,只有在上一次装载之后修改了文件的情况下,它才重新读取文件的内容。此函数通过调用 fread() 装载文件数据,把数据复制到另一个结构中,然后使用 strcpy() 把数据从装载的字符串转移到全局字符串中。

  load_file() 函数是触发计时器时调用的函数。它通过调用 read_file() 装载内容,然后使用 RELOAD_TIMEOUT 值设置计时器,作为尝试装载文件之前的秒数。libevent 计时器使用 timeval 结构,允许按秒和毫秒指定计时器。计时器不是周期性的;当触发计时器事件时设置它,然后从事件队列中删除事件。sat答案

  使用与前面的示例相同的格式编译代码:$ gcc -o basichttpfile basichttpfile.c -levent。

  现在,创建作为数据使用的静态文件;默认文件是 sample.html,但是可以通过命令行上的第一个参数指定任何文件(见 清单 6)。

  清单 6. 创建作为数据使用的静态文件

  $ ./basichttpfile

  Loading file: sample.html (8046 bytes)

  Server started on port 8081

  现在,程序可以接受请求了,重新装载计时器也启动了。如果修改 sample.html 的内容,应该会重新装载此文件并在日志中记录一个消息。例如,清单 7 中的输出显示初始装载和两次重新装载:

  清单 7. 输出显示初始装载和两次重新装载

  $ ./basichttpfile

  Loading file: sample.html (8046 bytes)

  Server started on port 8081

  Reloading file: sample.html (8047 bytes)

  Reloading file: sample.html (8048 bytes)

  注意,要想获得最大的收益,必须确保环境没有限制打开的文件描述符数量。可以使用 ulimit 命令修改限制(需要适当的权限或根访问)。具体的设置取决与您的 OS,但是在 Linux? 上可以用 -n 选项设置打开的文件描述符(和网络套接字)的数量:托福答案
 

posted on 2014-01-03 23:11 好不容易 阅读(281) 评论(1)  编辑  收藏

评论

# re: libevent库定时器的使用 2014-01-10 14:59 笑面虎

huigongzuo.com丨51fsk.com | peixunt.com | luwuyou.com
  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
PK10开奖 PK10开奖