위에서 이어집니다.
nginx는 콘솔에서 단일 프로세스로 실행됩니다. core/nginx.c의 기본 메소드를 읽어보세요. 앞의 코드는 모두 초기화 코드이므로 먼저 읽어보지 않으면 넘어지기 쉽습니다. 디테일의 고리 속으로. os/unix/ngx_process_cycle.c에서 ngx_single_process_cycle의 정의를 직접 찾으세요.
첫 번째 for 루프에 다음 코드를 추가합니다.
<code><span>for</span> (i = <span>0</span>; ngx_modules[i]; i++) { <span>char</span> * p = NULL; <span>if</span> (ngx_modules[i]->commands != NULL) { p = ngx_modules[i]->commands->name.data; } <span>if</span> (ngx_modules[i]->init_process) { <span>if</span> (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { <span>/* fatal */</span><span>exit</span>(<span>2</span>); } <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s init process\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p); } <span>else</span> { <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p); } } <span>printf</span>(<span>"[ngx_process_cycle] for ngx_modules init done\n"</span>);</code>
이 함수는 현재 nginx에 있는 모듈과 관련 인덱스 및 이름을 인쇄하는 것입니다.
두 번째 for 루프에서는 주로 ngx_process_events 메소드입니다. 검색해본 결과 이것이 매크로이고, 이 매크로는 epoll 모듈을 로드했기 때문에 이벤트에 있습니다. /modules/ngx_epoll_module.c
코드는 다음에서 발견되었습니다:
<code>ngx_event_actions = ngx_epoll_module_ctx.actions;</code>
ngx_process_events 메서드는 실제로 ngx_epoll_module_ctx 모듈의 작업에 있는 ngx_epoll_process_events 메서드인 것으로 나타났습니다. 이 메서드에서 epoll_wait 메서드가 호출되는 위치를 찾아 다음 코드를 추가합니다.
<code><span>printf</span>(<span>"[ngx_epoll_module] epoll wait\n"</span>); events = epoll_wait(ep, event_list, nevents, timer); <span>printf</span>(<span>"[ngx_epoll_module] epoll wait ---\n"</span>);</code>
실행 결과를 다시 만듭니다.
[main] to start ngx_single_process_cycle
[ngx_process_cycle] 모듈 ctx_index=0 색인=0 이름=데몬
[ngx_process_cycle] 모듈 ctx_index=0 색인=1 이름=error_log
[ngx_process_cycle] 모듈 ctx_index=0 색인=2 이름=포함
[ngx_process_cycle] 모듈 ctx_index=0 색인=3 이름=이벤트
[ngx_process_cycle] 모듈 ctx_index=0 색인=4 이름=연결 초기화 프로세스
[ngx_process_cycle] 모듈 ctx_index=1 색인=5 이름=rtsig_signo
[ngx_process_cycle] 모듈 ctx_index=2 색인=6 이름=epoll_events
[ngx_process_cycle] 모듈 ctx_index=0 색인=7 이름=http
[ngx_process_cycle] 모듈 ctx_index=0 색인=8 이름=서버
[ngx_process_cycle] 모듈 ctx_index=1 색인=9 이름=log_format
[ngx_process_cycle] 모듈 ctx_index=2 색인=10 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=3 색인=11 이름=색인
[ngx_process_cycle] 모듈 ctx_index=4 색인=12 이름=허용
[ngx_process_cycle] 모듈 ctx_index=5 색인=13 이름=다시 쓰기
[ngx_process_cycle] 모듈 ctx_index=6 색인=14 이름=proxy_pass
[ngx_process_cycle] 모듈 ctx_index=7 색인=15 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=8 색인=16 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=9 색인=17 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=10 색인=18 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=11 색인=19 이름=gzip
[ngx_process_cycle] 모듈 ctx_index=12 색인=20 이름=charset_map
[ngx_process_cycle] 모듈 ctx_index=13 색인=21 이름=사용자 ID
[ngx_process_cycle] 모듈 ctx_index=14 색인=22 이름=만료
[ngx_process_cycle] 모듈 ctx_index=15 색인=23 이름=output_buffers
[ngx_process_cycle] 모듈 ctx_index=16 색인=24 이름=(null)
[ngx_process_cycle] 모듈 ctx_index=17 색인=25 이름=(null)
[ngx_process_cycle] ngx_modules 초기화 완료
[ngx_epoll_module] epoll 잠깐만요
^C[ngx_epoll_module] epoll wait —
총 25개의 모듈을 찾았습니다. 연결 모듈에만 init_process 메서드가 있고 일부 모듈 이름이 비어 있습니다. 마지막으로 프로그램은 epoll 모듈에 들어가고 epoll_wait 호출에서 차단됩니다. 후속 인쇄 문은 CTRL+C가 시작된 후에만 실행됩니다.
여기서 nginx의 모듈 정의를 자세히 살펴볼 수 있습니다. 코드를 보면 nginx에서 사용되는 실제 유형이 모두 _t로 끝나는 것을 쉽게 알 수 있습니다. , 실제 유형은 _s로 끝납니다. nginx_module_s는 core/ngx_conf_file.h 파일에 정의되어 있습니다.
<code><span>struct</span> ngx_module_s { ngx_uint_t ctx_index; ngx_uint_t index; <span>void</span> *ctx; ngx_command_t *commands; ngx_uint_t type; ngx_int_t (*init_module)(ngx_cycle_t *cycle); ngx_int_t (*init_process)(ngx_cycle_t *cycle); <span>#if 0</span> ngx_int_t (*init_thread)(ngx_cycle_t *cycle); <span>#endif</span> };</code>
두 개의 인덱스 번호, 명령 및 3개의 함수가 있으며 구체적인 의미는 나중에 사용됩니다.
ngx_event_module_t와 ngx_event_actions_t라는 두 가지 다른 구조가 있습니다. 후자는 전자의 멤버이지만 이는 추상적이며 특정 플랫폼에 따라 다른 유형이 있습니다. 에폴 .
ngx_event_module_t는 다음과 같습니다.
<code>typedef struct { ngx_str_t <span>*name</span>; void <span>*(</span><span>*create_conf</span>)(ngx_cycle_t <span>*cycle</span>); char <span>*(</span><span>*init_conf</span>)(ngx_cycle_t <span>*cycle</span>, void <span>*conf</span>); ngx_event_actions_t actions; } ngx_event_module_t;</code>
epoll 인스턴스는 다음과 같습니다.
<code>ngx_event_module_t ngx_epoll_module_ctx = { &epoll_name, ngx_epoll_create_conf, <span>/* create configuration */</span> ngx_epoll_init_conf, <span>/* init configuration */</span> { ngx_epoll_add_event, <span>/* add an event */</span> ngx_epoll_del_event, <span>/* delete an event */</span> ngx_epoll_add_event, <span>/* enable an event */</span> ngx_epoll_del_event, <span>/* disable an event */</span> ngx_epoll_add_connection, <span>/* add an connection */</span> ngx_epoll_del_connection, <span>/* delete an connection */</span><span>NULL</span>, <span>/* process the changes */</span> ngx_epoll_process_events, <span>/* process the events */</span> ngx_epoll_init, <span>/* init the events */</span> ngx_epoll_done, <span>/* done the events */</span> } };</code>
ngx_event_module_t의 actions 멤버는 epoll과 관련된 일부 함수로 ngx_epoll_module_ctx에 정의되어 있으며, 이전 ngx_process_events는 다음 두 줄의 코드가 연결되어 정의됩니다.
<code><span>#<span>define</span> ngx_process_events ngx_event_actions.process_events</span></code>
event/ngx_event.h에서
<code><span> ngx_event_actions </span>=<span> ngx_epoll_module_ctx.actions;</span></code>
ngx_event_actions는 event/ngx_event.c에서 전역 변수로 정의됩니다.
<code>ngx_event_actions_t ngx_event_actions;</code>
다음으로 nginx에서 epoll의 사용을 살펴보십시오.
계속…
위 내용은 nginx 소스코드(4)의 주요 프로세스를 다양한 측면을 포함하여 소개하고 있어 PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.