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

nng协议nni_taskq_sys_init(void) 对nni_taskq_systq 初始化

        函数调用关系:nni_init(void)  --> nni_plat_init(nni_init_helper) 今天分析的函数位于 nni_init_helper()函数中的 nni_taskq_sys_init() 。  这个函数主要用于针对 全局变量  nni_taskq_systq 进行申请空间并初始化。 

1. 确定线程数量 num_thr  

        这个通过宏定义或者函数获得。 没定义则取CPU数量 * 2; 最大值为16. 如果小于2, 则指定num_thr 的值为2. 最少2个,最多16个。 

2.执行初始化   nni_taskq_init(&nni_taskq_systq, num_thr)

nni_taskq 的定义:

struct nni_taskq_thr{nni_taskq *tqt_tq;nni_thr    tqt_thread;
}  struct    nni_taskq {nni_list       tq_tasks;nni_mtx        tq_mtx;nni_cv         tq_sched_cv;nni_cv         tq_wait_cv;nni_taskq_thr  *tq_threads;int            tq_nthreads;bool           tq_run;
}

基本步骤:

1. 为tq 申请空间, 为tq->tq_threads  申请内存空间

2. 对线程数量赋值,tq->tq_nthreads = nthr .

3. 链表初始化   nni_taskq_systq->tq-tasks 互斥锁初始化, 条件变量初始化

//请详细分析并给出使用范例
nni_mtx_init(&tq->mtx);
nni_cv_init(&tq->tq_sched_cv, &tq->tq_mtx);
nni_cv_init(&tq->tq_wait_cv, &tq->tq_mtx);

4. 循环对全局变量nni_taskq_systq 的成员变量 所有的  tq_threads[i] 进行初始化。

5. th_threads[i] 的初始化流程:

        tq->th_threads[i].tqt_tq = tq;

        执行nni_thr_init tqt_thread[i].tqt_thread 进行初始化。 这个函数和其他的初始化类似,首先对第一层变量进行赋值,然后调用nni_plat_thr_init,初始化后的值为:

//tq的类型是  nni_taskq  *tq;
nni_thr_init(&tq->tq_threads[i].tqt_thread, nni_taskq_thread, &tq->tq_threads[i]);tq->tq_threads[i].tqt_tq = tq;&tq->tq_threads[i].tqt_thread 的类型是nni_thr
//nni_thr_init
tq->tq_threads[i].tqt_thread->done  = 0;
tq->tq_threads[i].tqt_thread->start = 0;
tq->tq_threads[i].tqt_thread->stop  = 0;
tq->tq_threads[i].tqt_thread->fn    = nni_taskq_thread;
tq->tq_threads[i].tqt_thread->arg   = &tq->tq_threads[i];//tq->tq_threads[i].tqt_thread->thr的类型是 nni_plat_thr//nni_plat_thr_init(&thr->thr, nni_thr_wrap, thr)
tq->tq_threads[i].tqt_thread->thr->func = nni_thr_wrap;
tq->tq_threads[i].tqt_thread->thr->arg  = tq->tq_threads[i].tqt_thread;

在nni_plat_thr_init(nni_plat_thr *thr, void (*fn)(void *), void *arg)中创建线程,执行线程函数:nni_plat_thr_main(void *arg);

在线程函数中调用函数指针:thr->func(thr->arg);  也就是nni_plat_init  初始化的thr->func 亦即:nni_thr_wrap,参数是nni_plat_init 中设置的参数,这里是  &tq->tq_threads[i];由于初始化时,start==0, stop==0 所以函数将等待在条件变量上。

static void
nni_thr_wrap(void *arg)
{nni_thr *thr = arg;int      start;nni_plat_mtx_lock(&thr->mtx);while (((start = thr->start) == 0) && (thr->stop == 0)) { //初始化条件,函数将等待在条件变量nni_plat_cv_wait(&thr->cv);}nni_plat_mtx_unlock(&thr->mtx);if ((start) && (thr->fn != NULL)) {thr->fn(thr->arg);}nni_plat_mtx_lock(&thr->mtx);thr->done = 1;nni_plat_cv_wake(&thr->cv);nni_plat_mtx_unlock(&thr->mtx);
}

在 nni_taskq_init 的最后,这里将执行nni_thr_run 函数,设置条件 start == 1 并唤醒等待在条件变量上的线程。

for (int i = 0; i < tq->tq_nthreads; i++) {nni_thr_run(&tq->tq_threads[i].tqt_thread);
}

函数继续执行,调用  nni_taskq_thread函数,参数是  &tq->tq_threads[i] ;

        

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python从0到100(四十三):数据库与Django ORM 精讲
  • LeetCode 129, 133, 136
  • 鸿蒙界面开发
  • Redis 主从搭建
  • 过滤出List集合的元素是Person对象,过滤出每个元素非null的name字段得到String类型的集合
  • vue侦听器(Watch)精彩案例剖析一
  • Redission中的Lua脚本写法、理解
  • Python面试题:Python中的单例模式及其实现
  • 基于单片机控制的锂电池充电和保护系统研究
  • 项目实战二
  • 利用Java调用人脸身份证比对接口
  • Prometheus监控Elasticsearch
  • 聚观早报 | Meta将推出新款AR眼镜;iPhone SE 4将升级显示屏
  • shell脚本教程学习
  • Qt:26.Qt项目:贪吃蛇游戏
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • [NodeJS] 关于Buffer
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • echarts的各种常用效果展示
  • JavaScript设计模式之工厂模式
  • Java比较器对数组,集合排序
  • java取消线程实例
  • Spring Boot MyBatis配置多种数据库
  • Webpack 4x 之路 ( 四 )
  • zookeeper系列(七)实战分布式命名服务
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 使用 Docker 部署 Spring Boot项目
  • 微信公众号开发小记——5.python微信红包
  • 【干货分享】dos命令大全
  • ​secrets --- 生成管理密码的安全随机数​
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (02)Hive SQL编译成MapReduce任务的过程
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (待修改)PyG安装步骤
  • (二)windows配置JDK环境
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .bat批处理出现中文乱码的情况
  • .net wcf memory gates checking failed
  • .NET 表达式计算:Expression Evaluator
  • .net(C#)中String.Format如何使用
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .Net各种迷惑命名解释
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [AI]文心一言爆火的同时,ChatGPT带来了这么多的开源项目你了解吗
  • [AutoSar]BSW_Com02 PDU详解
  • [AX]AX2012 R2 出差申请和支出报告
  • [BZOJ2208][Jsoi2010]连通数
  • [C#]使用C#部署yolov8-seg的实例分割的tensorrt模型
  • [C++] C++11详解 (一)
  • [C++] 从零实现一个ping服务