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的执行(待续。。。)

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

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

相关文章

影院选座系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;影院信息管理&#xff0c;电影类型管理&#xff0c;放映厅管理&#xff0c;电影信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;影院信息&…

Node.js实现文件下载

1.设置响应头&#xff1a; 使用 res.writeHead 设置适当的响应头&#xff0c;包括 Content-Type 和 Content-Disposition 以触发下载对话框。 2.创建文件读取流&#xff1a; 使用 fs.createReadStream 创建文件读取流&#xff0c;并通过 pipe 方法将其连接到响应对象 res&#…

学习小记-Nacos的服务注册与发现原理

服务注册&#xff1a; 当一个服务实例启动时&#xff0c;它会向 Nacos 服务器注册自己的信息&#xff0c;包括 IP 地址、端口号、元数据&#xff08;如服务版本、区域信息等&#xff09;。服务实例使用 Nacos API 发送注册请求&#xff0c;Nacos 服务器接收请求并存储服务实例信…

oracle数据字典详解

数据字典 1、动态数据字典是以v$xxx开始的数据字典&#xff0c;在数据库中约有150个左右&#xff0c;这些数据字典反映数据库动态运行状况&#xff0c;在不同时间查询会得到不同的结果。 2、DBA数据字典是以DBA_xxx表示&#xff0c;该数据字典存储数据库结构&#xff0c;查询…

[iOS]浅析isa指针

[iOS]浅析isa指针 文章目录 [iOS]浅析isa指针isa指针isa的结构isa的初始化注意事项 上一篇留的悬念不止分类的实现 还有isa指针到底是什么 它是怎么工作的 class方法又是怎么运作的 class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags 这里面的class又是何方…

7、核心:可扩展的共享内存数组结构-分块映射表和数组头

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 这篇是重点&#xff0c;如何构…

关于pip Install与conda install

conda解决依赖的问题很弱&#xff0c;环境包多了以后经常要解决依赖几分钟到十几分钟。我个人感觉比较好的实践是conda创建虚拟环境&#xff0c;装torch/tensorflow等比较难装的包&#xff0c;基础环境配好以后&#xff0c;后面装包一律用pip。 conda&#xff0c;pip&#xff0…

Netty Websocket

一、WebSocket 协议概述 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务端主动向客户端推送数据&#xff0c;从而实现了实时通信。WebSocket 建立在 HTTP 之上&#xff0c;但与 HTTP 的轮询&#xff08;Polling&#xff09;和长轮询&#xff08;Long Pol…

python的tkinter、socket库开发tcp的客户端和服务端

一、tcp通讯流程和开发步骤 1、tcp客户端和服务端通讯流程图 套接字是通讯的利器&#xff0c;连接时要经过三次握手建立连接&#xff0c;断开连接要经过四次挥手断开连接。 2、客户端开发流程 1&#xff09;创建客户端套接字 2&#xff09;和服务端器端套接字建立连接 3&#x…

Linux·基本指令(下)

1. mv 指令 (move) 语法&#xff1a;mv[选项] 源文件或目录 目标文件或目录 功能&#xff1a;将源文件或目录剪贴到一个新位置&#xff0c;或给源文件或目录改名但不会改变其内容 常用选项&#xff1a; -f &#xff1a;force 强制&#xff0c;如果目标文件已经存在&#xff0c;…

HCIE-AI大模型直通车火热报名中

第一阶段&#xff1a;HCIA-AI Solution Architect&#xff08;直播&#xff0c;39课时&#xff09; 该阶段详细介绍 AI 大模型所需基础技术栈&#xff0c;包含深度学习基础、计算机视觉技术、自然语言处理技术、华为开源深度学习框架 MindSpore、注意力制、Transformer 架构&am…

Spock单元测试框架使用介绍和实践

背景 单元测试是保证我们写的代码是我们想要的结果的最有效的办法。根据下面的数据图统计&#xff0c;单元测试从长期来看也有很大的收益。 单元测试收益: 它是最容易保证代码覆盖率达到100%的测试。可以⼤幅降低上线时的紧张指数。单元测试能更快地发现问题。单元测试的性…

CentOS Stream 卸载 Podman 并安装 Docker 的方法

目录 卸载 Podman 安装 Docker Podman 是一个无守护进程的容器引擎&#xff0c;旨在提供与 Docker 类似的命令行接口&#xff0c;但不需要守护进程运行。Podman 是 Red Hat 的开源项目&#xff0c;具有安全性、兼容性和灵活性等优点。 CentOS Stream 默认安装了 Podman 来代…

【spring boot】初学者项目快速练手

一小时带你从0到1实现一个SpringBoot项目开发_哔哩哔哩_bilibili 一、简介 二、项目结构 三、代码结构 1.生成框架 Spring Initializr 快速生成一个初始的项目代码&#xff0c;会生成一个demo文件 打开intellj idea&#xff0c;导入demo文件 2.目录结构 源码都放在src-ma…

“论软件维护方法及其应用”精选范文,软考高级论文,系统架构设计师论文

论文真题 软件维护是指在软件交付使用后&#xff0c;直至软件被淘汰的整个时间范围内&#xff0c;为了改正错误或满足 新的需求而修改软件的活动。在软件系统运行过程中&#xff0c;软件需要维护的原因是多种多样的&#xff0c; 根据维护的原因不同&#xff0c;可以将软件维护…

Lua基础知识入门

1 基础知识 标识符&#xff1a;标识符的定义和 C语言相同&#xff1a;字母和下划线_ 开头&#xff0c; 下划线_ 大写字母一般是lua保留字&#xff0c; 如_VERSION 全局变量&#xff1a;默认情况下&#xff0c;变量总是认为是全局的&#xff0c;不需要申明&#xff0c;给一个变…

window服务器thinkphp6 路由错误index.php

一&#xff0c;问题说明 访问——站点/index.php/admin/system/global————出现404错误 不想去掉index.php&#xff0c;想要保留这个————必须配置伪静态 默认的伪静态&#xff0c;是不要index.php&#xff0c;用来隐藏index.php&#xff0c;&#xff08;通过伪静态加…

电脑压缩视频文件 电脑压缩视频大小的方法

在数字化时代&#xff0c;视频已成为我们记录生活、分享快乐的重要工具。然而&#xff0c;大尺寸的视频文件常常让分享和存储变得棘手。如何在保持视频画质的前提下&#xff0c;轻松减小视频文件大小&#xff1f;今天&#xff0c;就让我们一起探索苹果电脑上的几种高效视频压缩…

Java中的方法重载详解

Java中的方法重载详解 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 方法重载的定义和特点 方法重载&#xff08;Method Overloading&#xff09;指在同一个类中&#xff0c;允许有多个同名方…

HP Superdome2小型机监控指标解读

监控易是一款专注于IT基础设施监控的软件&#xff0c;能够实时监控服务器的各项性能指标&#xff0c;确保服务器的稳定运行。针对HP Superdome2小型机&#xff0c;监控易通过IPMI和网页抓取数据的方式&#xff0c;监测包括服务器温度、风扇及电压等在内的关键指标&#xff0c;为…