159 Linux C++ 通讯架构实战14,epoll 函数代码实战

ngx_epoll_init函数的调用

    //(3.2)ngx_epoll_init函数的调用(要在子进程中执行)
    //四章,四节 project1.cpp:nginx中创建worker子进程;
    //nginx中创建worker子进程
    //官方nginx ,一个master进程,创建了多个worker子进程;
    // master process ./nginx 
    // worker process
    //(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)    sigemptyset(&set); 
    //(i)    for ( ;; ) {}.                //父进程[master进程]会一直在这里循环

ngx_epoll_init 函数内容

#和网络相关
[Net]
#监听的端口数量,一般都是1个,当然如果支持多于一个也是可以的
ListenPortCount = 2
#ListenPort+数字【数字从0开始】,这种ListenPort开头的项有几个,取决于ListenPortCount的数量,
ListenPort0 = 80
ListenPort1 = 443#epoll连接的最大数【是每个worker进程允许连接的客户端数】,实际其中有一些连接要被监听socket使用,实际允许的客户端连接数会比这个数小一些
worker_connections = 1024

//初始化函数【fork()子进程之前干这个事】
//成功返回true,失败返回false
bool CSocekt::Initialize()
{ReadConf();  //读配置项bool reco = ngx_open_listening_sockets();  //打开监听端口return reco;
}//专门用于读各种配置项
void CSocekt::ReadConf()
{CConfig *p_config = CConfig::GetInstance();m_worker_connections = p_config->GetIntDefault("worker_connections",m_worker_connections); //epoll连接的最大项数m_ListenPortCount    = p_config->GetIntDefault("ListenPortCount",m_ListenPortCount);       //取得要监听的端口数量return;
}

    //连接池: 数组,元素数量就是worker_connections【1024】,每个数组元素类型为 ngx_connection_t【结构】; ---结构数组;
     //为什么要引入这个数组:  2个监听套接字, 用户连入进来,每个用户多出来一个套接字;
       //把 套接字数字跟一块内存捆绑,达到的效果就是将来我通过这个套接字,就能够把这块内存拿出来;

初始化 连接池

当执行完成如下的代码后,参考图

    do {i--;   //注意i是数字的末尾,从最后遍历,i递减至数组首个元素//好从屁股往前来---------c[i].data = next;         //设置连接对象的next指针,注意第一次循环时next = NULL;c[i].fd = -1;             //初始化连接,无socket和该连接池中的连接【对象】绑定c[i].instance = 1;        //失效标志位设置为1【失效】,此句抄自官方nginx,这句到底有啥用,后续再研究c[i].iCurrsequence = 0;   //当前序号统一从0开始//----------------------next = &c[i]; //next指针前移} while (i); //循环直至i为0,即数组首地址m_pfree_connections = next;            //设置空闲连接链表头指针,因为现在next指向c[0],注意现在整个链表都是空的m_free_connection_n = m_connection_n;  //空闲连接链表长度,因为现在整个链表都是空的,这两个长度相等;

ngx_get_connection()重要函数:从连接池中找空闲连接;注意在这段代码中 应该只是给 监听fd 一个空闲连接对象。

	for(pos = m_ListenSocketList.begin(); pos != m_ListenSocketList.end(); ++pos){c = ngx_get_connection((*pos)->fd); //从连接池中获取一个空闲连接对象

理论上,后面应该要给每一个connectfd也要给一个 空闲连接对象。

    //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

    //总结:
    //a)epoll_create();epoll_ctl();
    //b)连接池技巧ngx_get_connection(),ngx_free_connection();学习这种编程方法;
    //c)同时传递 一个指针和一个二进制数字技巧;

    //(3.2)ngx_epoll_init函数的调用(要在子进程中执行)
    //四章,四节 project1.cpp:nginx中创建worker子进程;
    //nginx中创建worker子进程
    //官方nginx ,一个master进程,创建了多个worker子进程;
    // master process ./nginx 
    // worker process
    //(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)    sigemptyset(&set); 
    //(i)    for ( ;; ) {}.                //父进程[master进程]会一直在这里循环

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/587996.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费图片转excel方案大全

随着信息技术的发展&#xff0c;我们经常会遇到需要将图片中的数据转换成Excel表格的情况。这种需求在数据分析、报表制作、信息整理等领域尤为常见。然而&#xff0c;许多人在面对这一任务时感到困惑&#xff0c;不知道如何进行。本文将为大家介绍几种免费的图片转Excel方案&a…

分享高质量嵌入式软件的开发技巧

大家好&#xff0c;今天给大家介绍分享高质量嵌入式软件的开发技巧&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 高质量嵌入式软件的开发技巧涉及多个方面&#xff0c;从设计、…

Mybatis——一对一映射

一对一映射 预置条件 在某网络购物系统中&#xff0c;一个用户只能拥有一个购物车&#xff0c;用户与购物车的关系可以设计为一对一关系 数据库表结构&#xff08;唯一外键关联&#xff09; 创建两个实体类和映射接口 package org.example.demo;import lombok.Data;import …

Linux(05) Debian 系统修改主机名

查看主机名 方法1&#xff1a;hostname hostname 方法2&#xff1a;cat etc/hostname cat /etc/hostname 如果在创建Linux系统的时候忘记修改主机名&#xff0c;可以采用以下的方式来修改主机名称。 修改主机名 注意&#xff0c;在linux中下划线“_”可能是无效的字符&…

IDEA中连接SQLserver数据库(DataGrip相同连接)

IDEA中连接SQLserver数据库(DataGrip相同连接) 1. 打开IDEA-database组件 2. 新建SQL server连接 3. 填写信息进行连接 填写连接名称&#xff0c;连接主机IP&#xff0c;端口&#xff0c;默认端口1433&#xff0c;数据库用户名密码&#xff0c;默认数据库用户名是sa 第一次连接…

elment UI el-date-picker 月份组件选定后提交后台页面显示正常,提交后台字段变成时区格式

需求&#xff1a;要实现一个日期的月份选择<el-date-picker :typeformData.dateType :value-formatdateFormat v-modelformData.leaveFactoryDateplaceholder选择月份></el-date-picker>错误示例&#xff1a;将日期显示类型(type)dateType或将日期绑定值的格式(val…

Android Studio学习8——点击事件

在xml代码中绑定 在java代码中绑定 弹出一个toast 随机&#xff0c;数组

算法打卡day32|贪心算法篇06|Leetcode 738.单调递增的数字、968.监控二叉树

算法题 Leetcode 738.单调递增的数字 题目链接:738.单调递增的数字 大佬视频讲解&#xff1a;单调递增的数字视频讲解 个人思路 这个题目就是从例子中找规律&#xff0c;例如 332&#xff0c;从后往前遍历&#xff0c;32不是单调递增将2变为9,3减1&#xff0c;变成了329&…

面试题:MySQL 事务 日志 MVCC

事务的特性 ACID 事务的隔离级别 并发事务问题 脏读&#xff1a;一个事务读到另一个事务还没有提交的数据不可重复读&#xff1a;一个事务先后读取同一条记录&#xff0c;但两次读取的数据不同幻读&#xff1a;一个事务按照条件查询数据时&#xff0c;没有对应的数据行&#xf…

隐私计算实训营第七讲-隐语SCQL的架构详细拆解

隐私计算实训营第七讲-隐语SCQL的架构详细拆解 文章目录 隐私计算实训营第七讲-隐语SCQL的架构详细拆解1.SCQL Overview1.1 多方数据分析场景1.2 多方数据分析技术路线1.2.1 TEE SQL方案1.2.2 MPC SQL方案 1.3 Secure Collaborative Query Language(SCQL)1.3.1 SCQL 系统组件1.…

VBA数据库解决方案第九讲:把数据库的内容在工作表中显示

《VBA数据库解决方案》教程&#xff08;版权10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

DolphinScheduler on k8s 云原生部署实践

文章目录 前言利用Kubernetes技术云原生平台初始化迁移基于Argo CD添加GitOpsDolphinScheduler 在 k8s 上的服务自愈可观测性集成服务网格云原生工作流调度从HDFS升级到S3文件技术总结 前言 DolphinScheduler 的高效云原生部署模式&#xff0c;比原始部署模式节省了95%以上的人…