通讯架构实战——5-08 通讯代码精粹之epoll函数实战2-2

 

一:ngx_epoll_process_events函数调用位置
    上节课:epoll_create();epoll_ctl();--我们目前已经做好准备 等待迎接客户端主动发起三次握手连入;
    介绍ngx_epoll_process_events();

    (i)ngx_master_process_cycle()        //创建子进程等一系列动作
    (i)    ngx_setproctitle()            //设置进程标题    
    (i)    ngx_start_worker_processes()  //创建worker子进程   
    (i)        for (i = 0; i < threadnums; i++)   //master进程在走这个循环,来创建若干个子进程
    (i)            ngx_spawn_process(i,"worker process");
    (i)                pid = fork(); //分叉,从原来的一个master进程(一个叉),分成两个叉(原有的master进程,以及一个新fork()出来的worker进程
    (i)                //只有子进程这个分叉才会执行ngx_worker_process_cycle()
    (i)                ngx_worker_process_cycle(inum,pprocname);  //子进程分叉
    (i)                    ngx_worker_process_init();
    (i)                        sigemptyset(&set);  
    (i)                        sigprocmask(SIG_SETMASK, &set, NULL); //允许接收所有信号
    (i)                        g_socket.ngx_epoll_init();  //初始化epoll相关内容,同时 往监听socket上增加监听事件,从而开始让监听端口履行其职责
    (i)                            m_epollhandle = epoll_create(m_worker_connections); 
    (i)                            ngx_epoll_add_event((*pos)->fd....);
    (i)                                epoll_ctl(m_epollhandle,eventtype,fd,&ev);
    (i)                    ngx_setproctitle(pprocname);          //重新为子进程设置标题为worker process
    (i)                    for ( ;; ) 
    (i)                    {
    (i)                        //子进程开始在这里不断的死循环
    (i)                        ngx_process_events_and_timers(); //处理网络事件和定时器事件
    (i)                            g_socket.ngx_epoll_process_events(-1); //-1表示卡着等待吧
    (i)                    }

    (i)    sigemptyset(&set); 
    (i)    for ( ;; ) {}.                //父进程[master进程]会一直在这里循环

    从ngx_epoll_process_events()的函数调用位置,我们能够感觉到:
    a)这个函数,仍旧是在子进程中被调用;
    b)这个函数,放在了子进程的for ( ;; ) ,这意味着这个函数会被不断的调用;

    二:ngx_epoll_process_events函数内容
    用户三次握手成功连入进来,这个“连入进来”这个事件对于我们服务器来讲,就是 一个监听套接字上的可读事件;
    (2.1)事件驱动:官方nginx本身的架构也被称为“事件驱动架构”;拆开:“事件”,“驱动”;
    “驱动”:汽车靠发动机驱动,人体的发动机就是心脏;
    “驱动”:动力的来源;驱动的问题,就是探讨程序怎么来干活的问题;
    “事件驱动”,无非就是通过获取事件,通过获取到的事件并根据这个事件来调用适当的函数从而让整个程序干活,无非就是这点事;

    三:ngx_event_accept函数内容
    a)accept4/accept
    b)ngx_get_connection/setnonblocking
    c)ngx_epoll_add_event
    (3.1)epoll的两种工作模式:LT和ET【面试可能问】
    LT:level trigged, 水平触发,这种工作模式 低速模式(效率差) -------------epoll缺省用次模式
    ET:edge trigged,  边缘触发/边沿触发,这种工作模式 高速模式(效率好)
    现状:所有的监听套接字用的都是 水平触发;   所有的接入进来的用户套接字都是  边缘触发

    水平触发的意思:来 一个事件,如果你不处理它,那么这个事件就会一直被触发;
    边缘触发的意思:只对非阻塞socket有用;来一个事件,内核只会通知你一次【不管你是否处理,内核都不再次通知你】;
           边缘触发模式,提高系统运行效率,编码的难度加大;因为只通知一次,所以接到通知后,你必须要保证把该处理的事情处理利索;
    程序高手能够洞察到很多普通程序员所洞察不到的问题,并且能够写出更好的,更稳定的,更少出错误的代码;


    四:总结和测试
    (1)服务器能够感知到客户端发送过来abc字符了;
    (2)来数据会调用ngx_wait_request_handler()

    五:事件驱动总结:nginx所谓的事件驱动框架【面试可能问到】
    我们的项目和官方nginx一样,都是事件驱动框架;
    总结事件驱动框架/事件驱动架构
    所谓事件驱动框架,就是由一些事件发生源【三次握手内核通知,事件发生源就是客户端】,通过事件收集器来手机和分发事件【调用函数处理】
    【事件收集器:epoll_wait()函数】【ngx_event_accept(),ngx_wait_request_handler()都属于事件处理器,用来消费事件】

    六:一道腾讯后台开发的面试题
    问题:使用Linux epoll模型,水平触发模式;当socket可写时,会不停的触发socket可写的事件,如何处理?

    /*
    答案:
        第一种最普遍的方式:
        需要向socket写数据的时候才把socket加入epoll【红黑树】,等待可写事件。接受到可写事件后,调用write或者send发送数据。当所有数据都写完后,把socket移出epoll。
        这种方式的缺点是,即使发送很少的数据,也要把socket加入epoll,写完后在移出epoll,有一定操作代价。

        一种改进的方式:
        开始不把socket加入epoll,需要向socket写数据的时候,直接调用write或者send发送数据。如果返回EAGAIN,把socket加入epoll,在epoll
        的驱动下写数据,全部数据发送完毕后,再移出epoll。
        这种方式的优点是:数据不多的时候可以避免epoll的事件处理,提高效率。
    */
                          

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一门linux下c++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++在linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值