nginx源码解读

值得参考的链接:https://tengine.taobao.org/book/module_development.html

多进程模式:
	ngx_master_process_cycle(cycle);
		(1)设置进程标题
		(2)开启工作进程,ngx_start_worker_processes(conf_ctx, core_module);
		(3)开启缓存管理进程, ngx_start_cache_manager_processes(cycle, 0);
		(4)进入循环,捕捉进程中发生的信号,针对信号做不同的处理
			4.1: 热更新配置的处理流程:
			if (ngx_new_binary) { <----nginx二进制文件更新
				ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN);
				ngx_start_cache_manager_processes(cycle, 0);
				// 设置某些标识
				continue;
			}
			// 更新cycle,重启工作进程和缓存管理线程
			cycle = ngx_init_cycle(cycle);
			ngx_cycle = cycle;
			ccf = ngx_get_conf(cycle->conf_ctx, ngx_core_module);
			ngx_start_worker_processes();
			ngx_start_cache_manager_processes();
			// 暂停100秒,等待新进程开启
			ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));

	ngx_start_worker_processes(cycle, proc_num, type)的流程:
		channel_t ch;
		ch.command = NGX_CMD_OPEN_CHANNEL;
		for(int i=0; i<proc_num; i++) {
			/* 衍生一个新进程,新进程执行ngx_worker_process_cycle函数 */
			ngx_spawn_process(cycle, ngx_worker_process_cycle, 
								(void *)(intptr_t)i, "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(cycle, &ch);
		}


	nginx中fork进程的代码:
		pid = fork();
		switch(pid) {
		case -1:
			// 错误处理,
		case 0:
			proc(cycle, data);    // 执行ngx_worker_process_cycle函数,参数为cycle和data
			break;
		default: 
			break;
		}

	ngx_worker_process_cycle函数处理流程:
		worker = (intptr_t) data; 	/* 作用是什么? */
		ngx_worker_process_init(cycle, worker);
		// 设置进程标题
		// 进入for循环
			(1)判断进程中ngx_exiting全局标识是否为true,	是则进程终止
			(2)ngx_process_events_and_timer(cycle); // 处理cycle中发生的事件,关键函数;
			(3)判断其他全局状态变量,调用相应的处理函数
	
	ngx_process_events_and_timers(cycle)的处理流程:
		if (ngx_use_accept_mutex) {
			if (ngx_accept_disabled > 0) // 
				ngx_accept_disabled--;
			else {
				if (ngx_trylock_accept_mutex(cycle) == ERROR)  // 获取互斥锁失败返回
					return;   
			}
		}
		delta = ngx_current_msec;  //事件处理的开始事件
		ngx_process_events(cycle, timer, flags);  <--- 事件处理的主要函数,
													   选择的I/O模型不同,ngx_process_events函数也不
													   一样;分析epoll I/O模型的事件处理过程;
													   对应epoll模块中ngx_epoll_process_events函数
		delta = ngx_current_msec - delta;   
		ngx_event_process_posted(cycle, &ngx_posted_accept_events); <--- 事件后处理函数

	
	epoll I/O模型事件处理code在event/module/ngx_epoll_module.c文件中定义;
		自定义的epoll_event数据结构
		typedef union epoll_data {  <---一个联合体数据类型
			void *ptr;
			int fd;
			uint32_t u32;
			uint64_t u64;
		} epoll_data_t;
		struct epoll_event {
			uint32_t events;   		<---事件个数
			epoll_data_t data;	 	<---具体的事件数据
		};
		
	epoll I/O模型处理事件的具体代码流程:
		events = epoll_wait(ep, event_list, (int)nevent, timer);  <--等待发生在ep上的事件,
																	 nevnets限制最大的事件数
		err = (events == -1) ? ERROR : 0;
		// 循环处理事件列表
		for (i=0; i<events; i++) {
			c = event_lists[i].data.ptr;  
			instance = (uintptr_t) c & 1;  // 判断c最后一位是否是0?
			c = (ngx_connection *)((uintptr_t)c & (uintptr_t) ~1); /*将c转为指向ngx_connection_t类型指针;*/
			// 针对ngx_connection_t类型数据进行操作;
			rev = c->read; 	<--- ngx_event_t类型的读事件
			// 			
		}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值