本文我们讲述一下Nginx cycle运行上下文相关的实现。
1. 函数ngx_destroy_cycle_pools()
这里销毁conf->temp_pool临时内存池与conf->pool.
2. 函数ngx_init_zone_pool()
注意这里cycle->shared_memory
只适合于大块内存共享,因为这里会用一个相对复杂的结构来管理该共享内存,该结构本身也会占用共享内存的一部分空间。下面画出一个大体示意图:
上面首先为该共享内存块创建一个互斥锁。然后调用ngx_slab_init(sp)来建立对该共享内存块的管理机制。
3. 函数ngx_create_pidfile()
这里会根据pid
指令设定的文件名称创建文件,然后向该文件中写入master进程的进程ID:
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
这里%P
的意思是打印ngx_pid_t
类型;而%N
是打印换行。
4. 函数ngx_delete_pidfile()
这里删除进程的PID文件。如果是处于升级过程,删除oldpid。
5. 函数ngx_signal_process()
这里首先打开进程的PID文件以获得进程id,然后向该进程发送名称为sig
的信号。
6. 函数ngx_test_lockfile()
nginx使用锁机制来实现accept mutex,并且顺序的来访问共享内存。在大多数的系统上,锁都是通过原子操作来实现的,因此会忽略配置文件中的lock_file file指令;而对于其他的一些系统,lock file机制会被使用。这里我们支持NGX_HAVE_ATOMIC_OPS
。
7. 函数ngx_reopen_files()
这里重新打开cycle->open_files
链表中指定的文件,设置打开文件的所有者为user
,权限为所有者读写权限
,并设置打开的文件CLOEXE
属性,然后再关闭原来的fd。
值得注意的是,最后还调用了ngx_log_redirect_stderr()
来重定向错误日志。这是因为我们对日志文件也做了reopen()操作,因此原来的日志句柄也发生了变化,需要进行重定向。
8. 函数ngx_shared_memory_add()
这里向cycle->shared_memory
链表中添加共享内存数据结构: 首先检查是否已经有相同名字的共享内存块,有的话则返回已经存在共享内存块(tag要相同); 否则插入到cycle->shared_memory链表中。
9. 函数ngx_clean_old_cycles()
这里是定时器的一个回调函数,用于清理old_cycle
。这里清理时会检查cycle->connections
,如果还有连接没有关闭,则暂时不对该cycle对应的pool进行清理。