当前位置: 首页 > news >正文

nng协议nni_posix_resolv_sysinit()系统初始化

        nni_posix_resolv_sysinit(void) 实现了一个初始化函数 nni_posix_resolv_sysinit,用于设置解析系统(resolver system)。它主要负责初始化解析线程池,用于并发处理域名解析请求。

源码:

int
nni_posix_resolv_sysinit(void)
{resolv_fini = false;nni_aio_list_init(&resolv_aios);#ifndef NNG_RESOLV_CONCURRENCY
#define NNG_RESOLV_CONCURRENCY 4
#endifresolv_num_thr = (int) nni_init_get_param(NNG_INIT_NUM_RESOLVER_THREADS, NNG_RESOLV_CONCURRENCY);if (resolv_num_thr < 1) {resolv_num_thr = 1;}// no limit on the maximum for nownni_init_set_effective(NNG_INIT_NUM_RESOLVER_THREADS, resolv_num_thr);resolv_thrs = NNI_ALLOC_STRUCTS(resolv_thrs, resolv_num_thr);if (resolv_thrs == NULL) {return (NNG_ENOMEM);}for (int i = 0; i < resolv_num_thr; i++) {int rv = nni_thr_init(&resolv_thrs[i], resolv_worker, NULL);if (rv != 0) {nni_posix_resolv_sysfini();return (rv);}}for (int i = 0; i < resolv_num_thr; i++) {nni_thr_run(&resolv_thrs[i]);}return (0);
}

过程分析:

1. 对全局变量resolv_aios初始化:

   这里首先贴一下resolv_aios 的类型:

//nni_list_node 的类型定义:
typedef struct nni_list_node {struct nni_list_node *ln_next;struct nni_list_node *ln_prev;
} nni_list_node;//nni_list 的类型定义:
typedef struct nni_list {struct nni_list_node ll_head;size_t               ll_offset;
} nni_list;//resolv_aios 的定义
static nni_list resolv_aios;

        基本流程:首先初始化全局变量 resolv_fini = false;  紧接着初始化了全局变量  resolv_aios  

这里简单插一句初始化的过程:nni_aio_list_init(&resolv_aios);

void
nni_aio_list_init(nni_list *list)
{NNI_LIST_INIT(list, nni_aio, a_prov_node);
}#define NNI_LIST_INIT(list, type, field) \nni_list_init_offset(list, offsetof(type, field))void
nni_list_init_offset(nni_list *list, size_t offset)
{list->ll_offset       = offset;list->ll_head.ln_next = &list->ll_head;list->ll_head.ln_prev = &list->ll_head;
}

简单分析一下就是,nni_aio_list_init()函数对全局变量 resolv_aios  的初始化操作。而nni_aio_list_init  的定义是一个宏:NNI_LIST_INIT,这个是通用的宏定义,其他初始化也会用到。在这个宏里,传入了3个参数:

第一个就是我们的全局变量的地址:&resolv_aios

第二个是 type类型,这里是  nni_aio 这个结构体

第三个是 a_prov_node

在宏里调用了函数 nni_list_init_offset (list,  offsetof(type,  field))这里的type就是 nni_aiofield是 a_prov_node offsetof是一个内核中常用的宏,用于计算结构体类型距离结构体首地址的偏移量。我们可以在代码中加一行计算这个值并输出:offserof aio -> a_prov_node=[408]。甚至我们可以通过内存对齐算一下这个值。

//在文件/src/platform/posix/posix_resolv_gai.c的480行添加下面的代码
printf("offserof aio -> a_prov_node=[%d]\n", offsetof(nni_aio, a_prov_node));
//我们将看到输出是 offserof aio -> a_prov_node=[408]

初始化之后的值为:

resolv_aios->ll_ofset  = 408;
resolv_aios->ll_head.ln_next = &resolv_aios->ll_head;
resolv_aios->ll_head.ln_prev = &resolv_aios->ll_head;

当然我们也可以直接在初始化完成后进行直接输出,经过验证:resolv_aios.ll_offset=[408];其实就是对全局变量 resolv_aios 的指针及 ll_offset 字段进行了初始化。结果如上。

  • resolv_fini 被设置为 false,表示解析系统还未完成。
  • nni_aio_list_init 函数初始化一个异步I/O列表 resolv_aios,用于存储待处理的解析请求。

2. 解析并发级别设置

  • 如果未定义 NNG_RESOLV_CONCURRENCY,则将其定义为 4。
  • 使用 nni_init_get_param 获取解析线程数,默认值为 NNG_RESOLV_CONCURRENCY
  • 确保解析线程数至少为 1。 

这里不做详细分析,感兴趣的同学请分析并留下链接,大家一起学习。

3. 分配解析线程结构数组

        分配  resolv_thrs 数组,大小为 resolv_num_thr ;

        分配失败则返回内存不足

4. 初始化和启动解析线程

        这里对 resolv_aios逐个(这里是4个,执行同样的操作)进行初始化。调用的函数是不是有点眼熟!nni_thr_init 。

这里的参数类型是 nni_thr (和前面一篇 nni_posix_global_pollq 初始化的成员变量是同一类型)。为方便查看,这里再次贴出nni_thr的类型定义:

struct nni_thr {nni_plat_thr thr;nni_plat_mtx mtx;nni_plat_cv  cv;nni_thr_func fn;void *       arg;int          start;int          stop;int          done;int          init;
};//上面结构体的成员变量
struct nni_plat_thr {pthread_t tid;void (*func)(void *);void *arg;
};

在 nni_thr_init  函数中,对每个resolv_thrs[i] 数组元素进行一次初始化操作,初始化之后的值是:

&resolv_thrs[i]->done  = 0;
&resolv_thrs[i]->start = 0;
&resolv_thrs[i]->stop  = 0;
&resolv_thrs[i]->fn    = resolv_worker;
&resolv_thrs[i]->arg   = NULL;

同样,对thr->thr 也会进行初始化,执行函数nni_plat_thr_init (&thr->thr, nni_thr_wrap, thr  );

初始化后的值是:

nni_thr的成员变量 nni_plat_thr
nni_thr->nni_plat_thr->func = nni_thr_wrap;
nni_thr->nni_plat_thr->arg  = nni_thr;

接下来创建一个线程, 线程的id 就是 nni_thr->nni_plat_thr->tid,线程属性沿用了前面初始化的线程属性。 执行线程函数 nni_plat_thr_main。在线程函数中,会执行函数

nni_thr->func(nni_thr->arg);这里就执行nni_thr初始化的函数 resolv_worker,回顾上面的初始化过程可知,参数是NULL。

这段代码通过设置并发解析线程池来初始化解析系统,用于处理异步域名解析请求。初始化过程中包括全局变量和AIO列表的初始化、解析并发级别的设置、解析线程结构数组的分配以及解析线程的初始化和启动。整个过程确保解析系统能够高效地并发处理解析请求。

5. resolv_worker的执行(待续。。。)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • iOS ------ ARC的工作原理
  • Android获取当前屏幕显示的是哪个activity
  • 访问控制系列
  • 【RPC注册发现框架实战】一个简易的RPC注册发现框架
  • Vue.js:如何区分页面关闭和刷新?深入解析与实战
  • mysql命令练习
  • 测试开发面经总结(三)
  • Qt篇——QSqlQueryModel内容居中显示
  • Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图
  • 服务器的80和443端口关闭也能申请SSL证书
  • 容器安全最佳实践和工具
  • 系统架构设计师教程 第3章 信息系统基础知识-3.5 专家系统-解读
  • Vue--Router(路由)
  • Scrapy 核心组件之Spiders组件的使用
  • java在继承的继承上添加新的属性和方法
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • 2017前端实习生面试总结
  • classpath对获取配置文件的影响
  • Java-详解HashMap
  • JS题目及答案整理
  • LeetCode18.四数之和 JavaScript
  • Redis在Web项目中的应用与实践
  • scrapy学习之路4(itemloder的使用)
  • 成为一名优秀的Developer的书单
  • 高程读书笔记 第六章 面向对象程序设计
  • 排序算法学习笔记
  • 前端代码风格自动化系列(二)之Commitlint
  • 人脸识别最新开发经验demo
  • 数据科学 第 3 章 11 字符串处理
  • 我与Jetbrains的这些年
  • 赢得Docker挑战最佳实践
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​如何防止网络攻击?
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # Kafka_深入探秘者(2):kafka 生产者
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #Ubuntu(修改root信息)
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (Java入门)学生管理系统
  • (Matlab)使用竞争神经网络实现数据聚类
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (ZT)一个美国文科博士的YardLife
  • (zt)最盛行的警世狂言(爆笑)
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二十三)Flask之高频面试点
  • (力扣题库)跳跃游戏II(c++)
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • .axf 转化 .bin文件 的方法
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案