Nginx process model
- Multi-process model of
inter-process independent of each other, no lock, and independently of each other;
a process to exit the operation does not affect other processes, reduce risk;
when the request comes, more worker to obtain a registration event by reading listenfd competition accrpt_mutex, reading events in the call accept to accept the connection.
- Non-blocking asynchronous:
processing a network event and I / O multiplexing the same, while monitoring a plurality of events, when an event is ready to go the read and write;
request a process to handle only a constantly switch between the request;
handover is asynchronous because the event is not ready to give up the initiative, similar to the loop handle multiple events prepared without any cost
- Signal
if Nginx in (when epoll_wait) wait event, program received signal, the signal handler after processing is complete, epoll_wait returns an error, then the program can be called again to enter epoll_wait
- Timer
Nginx With timer timeout epoll_wait implementation;
Nginx timer event is placed on a red-black tree inside the maintenance timer each time before entering epoll_wait, starting with the red-black tree to get all the timer event the minimum time, in the calculation of the timeout epoll_wait into the epoll_wait;
so, when there is no network events as they arrive, and no signal generation, epoll_wait time out, that is, to the timer event;
then Nginx will check all of the timeout event, they state is set to timeout, and then to deal with network events.
Nginx event handling model (pseudo-code)
while (true) {
for t in run_tasks:
t.handler();
update_time(&now);
timeout = ETERNITY; // 重置超时时间
for t in wait_tasks: /* sorted already */
if (t.time <= now) {
t.timeout_handler(); // 超时
} else {
timeout = t.time - now; // 更新超时时间
break;
}
nevents = poll_function(events, timeout); // I/O复用处理事件
for i in nevents:
task t;
if (events[i].type == READ) {
t.handler = read_handler;
} else { /* events[i].type == WRITE */
t.handler = write_handler;
}
run_tasks_add(t);
}