我读Mongoose源码----程序框架


分类: Unix网络编程   352人阅读  评论(4)  收藏  举报
Mongoose 源代码 线程 Unix

Mongoose是一种WEB服务器,因为最近在学习网络编程,所以打算研究研究它的源码,认真看了大部分,觉得学到的东西的确不少,拿出来分享一下,也和大家交流交流

至于什么是WEB服务器,以及Mongoose作为一种轻量级的WEB服务器,它有哪些优点,这里给个链接:http://www.cnblogs.com/skynet/archive/2010/07/24/1784322.html

刚开始,也是看作者的文章才产生兴趣读源码,所以分享很重要(^o^)

如果想快速的阅读源码,可以先预览一下UserManual.md这个文件,用户手册告诉我们怎么去使用这个服务器,以及如何使用它提供的功能。

好的,编译运行请看那位吴哥的文章,这里,我直接把我读源码的笔记整理出来:首先我们看程序的主体框架,细节决定成败,但是从整理上入手,我们能走的更远。

程序的框架:

Mongoose采用的是线程池模型,有两个关键的数据结构,mg_callbacks和mg_context,前者是一系列函数指针集合,在程序的执行过程中我们会调用这些函数,后者则是Mongoose的核心,数据结构后面单独分析,回到程序框架上来

[cpp]  view plain copy
  1. main(){  
  2. //处理用户的输入  
  3. process_command_line_arguments();  
  4. //设置中断信号  
  5. signal(SIGTERM, signal_handler);  
  6. signal(SIGINT, signal_handler);  
  7. //开始  
  8. mg_start();  
  9. while(exit_flag == 0)  
  10.     sleep(1);  
  11. //结束  
  12. mg_stop();  
  13. }  

程序的开始:

程序开始于mg_start,结束于mg_stop,在mg_start()中,分别生成主线程和工作线程,工作线程我们可以自己配置,默认是50个

mg_start_thread(master_thread,ctx)

mg_start_thread(worker_thread,ctx)

然后分为两条线路:

1.     Master_thread()中采用poll来处理监听套接字,对于每一个监听套接字,当有新的连接请求时,调用accept_new_connection()处理新的连接。accept_new_connection()中调用produce_socket()产生新的连接套接字,产生的连接套接字放入线程池队列中,因为是多线程,所以要考虑线程同步问题,这里采用了“生产者---消费者”模型,很好的处理了同步问题

2.     worker_thread()中作为消费者,我们调用consume_socket(),然后调用process_new_connection()来处理新的连接,实质是调用handle_request()函数,至此整个程序的框架一目了然

 

程序的结束:

我们在main函数中sleep了,当我们收到了信号例如键盘上的ctrl+c,

static voidWINCDECL signal_handler(int sig_num) {

  exit_flag = sig_num;

}

中修改了exit_flag,然后程序进入mg_stop(),

[cpp]  view plain copy
  1. void mg_stop(struct mg_context *ctx) {  
  2.   ctx->stop_flag = 1;  
  3.   while (ctx->stop_flag != 2) {  
  4.     (void) mg_sleep(10);  
  5.   }  
  6. }  

修改了mg->stop_flag = 1,然后等待其变为2, 其实就是去清理线程数据,我们在master_thread()中看到最后一句ctx->stop_flag = 2,至此,程序就退出了,以上就是程序的结束流程。

程序的框架图大体是这样的:

我读Mongoose源码----程序框架_第1张图片

你可能感兴趣的:(unix网络编程)