从零构建通讯器--5.6 通讯代码精粹之epoll函数实战1(连接池)

(1)一个更正,一个注意

更正:kquene->改正为kqueue
注意:即将进入最重要,最核心的内容讲解,戒骄戒躁,代码精华

(2)配置文件的修改

①增加worker_connections项,epoll连接的最大数,每个worker进程允许连接的客户端数
②在ngx_c_socket.cxx中增加ReadConf()函数,把配置文件的worker_connections读出来和取地端口数读出来
(代表着后续整个系统启动起来5个进程都在监听者两个窗口)

(3)epoll函数实战

epoll_create(),epoll_ctl(),epoll_wait();<<—系统提供的函数调用

(3.1)ngx_epoll_init函数内容

1)具体函数解释
①epoll_create():创建一个epoll对象,创建了一个红黑树,还创建了一个双向链表;(一定要有返回值)
*******************连接池说明*************************
②创建连接池: 数组,元素数量就是worker_connections【1024】,每个数组元素类型为 ngx_connection_t【结构】; ---结构数组;
 为什么要引入这个数组?
  监听两个端口80和443,就有2个监听套接字, 用户连入进来,每个用户多出来一个套接字,但是套接字本身是个数字,这样就可以-->>把 套接字数字跟一块内存捆绑,达到的效果就是将来我通过这个套接字,就能够把这块内存拿出来;(数组从后面连起来)
  *******************连接池说明*************************
  若遍历太慢,ngx搞了个空闲量(链表都是空闲的),m_pfree_connection始终指向空闲链接
  ③遍历所有监听的socket【监听端口】也就是监听套接字队列
  ngx_get_connection()重要函数:从连接池中找空闲连接;(ngx维护了空闲链表的链表)
  a)epoll_create()****************
  b)连接池(找空闲连接)
  c)ngx_epoll_add_event()**************
   epoll_ctl();
  d)ev.data.ptr = (void *)( (uintptr_t)c | c->instance);    把一个指针和一个位 域合二为一,塞到一个void *中去,后续能够把这两个值全部取出来,如何取,取出来干嘛,后续再说;

在这里插入图片描述
ps -eo pid,ppid,sid,tty,pgrp,comm,stat,cmd | grep -E ‘bash|PID|nginx’
如下命令用root权限执行
//sudo su 获得root权限
//lsof -i:80 列出哪些进程在监听80端口
//netstat -tunlp | grep 80


2)netstat和lsof的区别:

netstat只能显示正在监听该端口的进程中的某一个,不能显示所有

在这里插入图片描述
在这里插入图片描述

3)总结:

a)学习在商业代码中调用epoll_create(),epoll_ctl() , epoll_wait():

epoll_create();创建epoll ,
epoll_ctl();把读事件加入到红黑树中去
当客户端接入时,本项目服务器程序才能通过后续的epoll_wait得到通知(感受到)

b)连接池技巧(遍历很慢,从空闲连接池上找)

ngx_get_connection()从头上拽一个空闲的链表
ngx_free_connection()
学习这种编程方法;

c)同时传递 一个指针和一个二进制数字技巧;

(3.2)ngx_epoll_init函数的调用 (要在子进程中执行)

之前四章,四节官方nginx ,一个master进程,创建了多个worker子进程;
//(1)ngx_master_process_cycle()        //创建子进程等一系列动作
//(2)    ngx_setproctitle()            //设置进程标题    
//(2)    ngx_start_worker_processes()  //创建worker子进程   
//(3)        for (i = 0; i < threadnums; i++)   //master进程在走这个循环,来创建若干个子进程
//(4)            ngx_spawn_process(i,"worker process");
//(5)                pid = fork(); //分叉,从原来的一个master进程(一个叉),分成两个叉(原有的master进程,以及一个新fork()出来的worker进程
//(5)                //只有子进程这个分叉才会执行ngx_worker_process_cycle()
//(5)                ngx_worker_process_cycle(inum,pprocname);  //子进程分叉(要在子进程中执行ngx_epoll_init)
//(6)                    ngx_worker_process_init();
//(7)                        sigemptyset(&set);  
//(7)                        sigprocmask(SIG_SETMASK, &set, NULL); //允许接收所有信号
//(7)                        g_socket.ngx_epoll_init();  //初始化epoll相关内容,同时 往监听socket上增加监听事件,从而开始让监听端口履行其职责
//(8)                            m_epollhandle = epoll_create(m_worker_connections); //用epoll创建连接数
//(8)                            ngx_epoll_add_event((*pos)->fd....);//加入监听数
//(9)                                epoll_ctl(m_epollhandle,eventtype,fd,&ev);
//(9)                    ngx_setproctitle(pprocname);          //重新为子进程设置标题为worker process
//(10)                    for ( ;; ) {}. ....                   //子进程开始在这里不断的死循环
//(i)    sigemptyset(&set); //父进程进程继续其他的流程
//(i)    for ( ;; ) {}.                //父进程[master进程]会一直在这里循环

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值