Posted on 2011-09-27 11:26
冷鋒 閱讀(2226)
評論(0) 編輯 收藏 引用 所屬分類:
linux
由于工作需要,分析了nginx的連接層事件處理模塊,只是初步的大體分析。
mian函數(shù)(nginx.c)里面做一些初始化的工作,最主要的部分,是調(diào)用ngx_init_cycle,ngx_master_process_cycle(主進(jìn)程循環(huán)),
ngx_init_cycle主要是做一些初始化的工作,包括調(diào)用ngx_open_listening_sockets打開socket端口監(jiān)聽等。
ngx_master_process_cycle函數(shù)中,先設(shè)置一下需要阻塞的信號,然后是調(diào)用ngx_start_worker_processes函數(shù)創(chuàng)建worker進(jìn)程,然后進(jìn)入一個(gè)死循環(huán)。里面應(yīng)該是管理worker進(jìn)程的,主循環(huán)里面調(diào)用了sigsuspend函數(shù)掛起等待信號,具體怎么管理還沒研究。
ngx_start_worker_processes:調(diào)用ngx_spawn_process,循環(huán)創(chuàng)建N個(gè)worker進(jìn)程
ngx_spawn_process:調(diào)用socketpair創(chuàng)建用于父子進(jìn)程通信的socket,里面進(jìn)行了一大堆socket參數(shù)設(shè)置,然后調(diào)用worker進(jìn)程的主循環(huán)ngx_worker_process_cycle,
然后主進(jìn)程設(shè)置進(jìn)程表相應(yīng)信息。
ngx_worker_process_cycle:先調(diào)用ngx_worker_process_init初始化進(jìn)程,里面應(yīng)該是設(shè)置成守護(hù)進(jìn)程等等,有初始化模塊信息,關(guān)閉對等socket的其中一個(gè)channel,其中比較關(guān)鍵的是調(diào)用ngx_add_channel_event。里面調(diào)用ngx_get_connection返回一個(gè)free的ngx_connection_t,最關(guān)鍵的是ngx_add_conn,其對應(yīng)到epoll模塊的ngx_epoll_add_connection,在這里就是添加相應(yīng)的監(jiān)聽socket進(jìn)監(jiān)聽隊(duì)列,并設(shè)置連接為激活狀態(tài),可以看到這里epoll是用的ET模式。
接下來在ngx_worker_process_cycle中,檢查是否配置了多線程模式,如果有,就創(chuàng)建多線程,我只關(guān)注多進(jìn)程,因此先無視它,關(guān)鍵點(diǎn)是調(diào)用ngx_process_events_and_timers函數(shù),
ngx_process_events_and_timers:調(diào)用ngx_process_events和ngx_event_process_posted,
ngx_process_events對應(yīng)是ngx_epoll_process_events,這里會調(diào)用epoll_wait,就跟平常的epoll使用一樣。
ngx_event_process_posted(cycle, &ngx_posted_accept_events);處理accept隊(duì)列中所有事件,ngx_posted_accept_events沒有找到初始化的地方,估計(jì)是編譯腳本自動生成的,估計(jì)會對應(yīng)到ngx_event_accept函數(shù)進(jìn)行處理,里面就是普通的accept操作,返回fd,并生成一條ngx connection,然后調(diào)用ngx_add_conn加入epoll監(jiān)聽隊(duì)列。
至此,整個(gè)流程完成。
雖然還有很多地方不懂,但總算了解了大體流程了。以上分析不保證正確,僅供參考,僅作為個(gè)人學(xué)習(xí)筆記,歡迎指正。