Nginx 부자 프로 세 스 생 성 및 주체 작업 함수
기본적으로 부모 프로 세 스 (즉 메 인 프로 세 스) 는 처음부터 설정 을 초기 화하 고 읽 으 며 각 모듈 의 기능 을 불 러 온 다음 에 fork () 에서 N 키 프로 세 스 (즉 작업 프로 세 스) 를 꺼 내 같은 작업 논리 와 기능 을 가지 고 있 습 니 다.부모 프로 세 스 는 신호 (예 를 들 어 HUP, QUIT 등) 를 감청 하고 socket pair 를 통 해 하위 프로 세 스에 신 호 를 전달 합 니 다 (하위 프로 세 스 간 에는 일반적으로 통신 하지 않 습 니 다).하위 프로 세 스 는 부모 프로 세 스 가 전달 하 는 신 호 를 이벤트 로 처리 합 니 다.모든 하위 프로 세 스 가 서비스 감청 포트 (예 를 들 어 http 80) 를 공유 하기 때문에 사용자 가 요청 을 보 낼 때 하위 프로 세 스 의 이벤트 호출 함 수 를 터치 합 니 다.따라서 accept () 요청 을 할 때 mutex 를 사용 하여 하나의 작업 프로 세 스 만 요청 을 받 아들 이 고 처리 할 수 있 도록 해 야 합 니 다.
Nginx 메 인 프로 세 스 의 입 구 는 일반적인 프로그램 과 같은 main () 함수 입 니 다. 코드 는 다음 과 같 습 니 다.
int ngx_cdecl main(int argc, char *const *argv)
{
/*...*/
//nginx id,
// ngx_listening_t ( cycle->listening ),
// getsockname,getsockopt
// ngx_listening_t ,
// , ngx_init_cycle
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return 1;
}
/*...*/
//ngx_modules objs/ngx_modules.c
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++; //
}
//ngx_init_cycle() , , main, ngx_master_process_cycle
// ngx_single_process_cycle , reconfigure 。
// , cycle cycle ; old cycle ,
// log , , pool, shared mem, file handler,
//bind/listen socket , cycle
//
cycle = ngx_init_cycle(&init_cycle);
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
}
else {
//
ngx_master_process_cycle(cycle);
}
}
//ngx_start_worker_processes() , n, ngx_worker_process_cycle()
// ngx_spawn_process() work ;
// ngx_worker_process_cycle; worker
//worker ; (ngx_pass_open_channel())
//n worker process
//type , NGX_PROCESS_RESPAWN, NGX_PROCESS_JUST_RESPAWN
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
ngx_int_t i;
ngx_channel_t ch;
ch.command = NGX_CMD_OPEN_CHANNEL;
for (i = 0; i < n; i++) {
// config CPU
cpu_affinity = ngx_get_cpu_affinity(i);
//ngx_spawn_process ngx_process_slot
// slot
ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
"worker process", type);
ch.pid = ngx_processes[ngx_process_slot].pid;
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[0];
//ngx_pass_open_channel worker channel[0] id
// slot (ngx_write_channel())
// worker。
// , , worker worker
//channel[0]
ngx_pass_open_channel(cycle, &ch);
}
}
ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn)
{
/*...*/
// NGX_PROCESS_DETACHED, (
// ), socketpair。
if (respawn != NGX_PROCESS_DETACHED) {
// socketpair
// socketpair ,master worker
//socket, master socketpair channel[0],
//channel[1] 。
// worker , worker master
// socketpair。
// worker ( ngx_worker_process_init)
// socketpair channel[0] worker
//channel[1], socketpair channel[1]
//worker channel[0], socketpair
//channel[1] 。 , worker worker
//channel[0], sendmsg(channel[0], ...) worker
/*...*/
}
/*...*/
//
pid = fork();
switch (pid) {
case -1:
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"fork() failed while spawning "%s"", name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
// ,
case 0:
ngx_pid = ngx_getpid();
// ngx_worker_process_cycle()
// : ,
//
proc(cycle, data);
break;
default:
break;
}
}
//worker
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
//
// init_process
// channel[1] ,
// ngx_processes , channel[1]
// channel[0]
// channel[0] , sendmsg
// ngx_add_channel_event() , ngx_channel 。
ngx_worker_process_init(cycle, 1);
// ,
for ( ;; ) {
/*...*/
// epoll,
// ( ), ( )
// accept queue event queue
ngx_process_events_and_timers(cycle);
/*...*/
}
/*...*/
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java swing drawImagegetImage 가 즉시 돌아 오기 때문에 그림 이 불 러 올 때 까지 기다 리 지 않 고 프로그램 에서 다른 작업 을 수행 할 수 있 습 니 다.성능 을 향상 시 킬 수 있 지만 효과 적 인 프로그램 은 더 많은 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.