线程间传递比较大的结构数组的最佳方案

By admin at 2021-05-03 • 1人收藏 • 924人看过

最近遇到个问题:

上次说到那个光纤分析仪的dll里会返回一个结构体 , 内部有两个记录了7500个位置的数组, 

需要在一个线程里连续读取这个dll的返回数组, 然后更新并返回给其他线程使用.

之前用thread.set("pos1",table_A)来传递到其他线程, 测试结果发现这句话需要执行30毫秒左右,然后我换成thread.table, 执行结果20毫秒左右,感觉这种方式效率比较低, 那么有没有其他方式?

经过我的各种测试,最终得出的结论如下:

答案:使用raw.copy()直接操作指针. 时间基本上在1ms以内了.


image.png


import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=759;bottom=469)
winform.add(
button2={cls="button";text="(连续) 线程中修改数值";left=71;top=78;right=319;bottom=157;font=LOGFONT(h=-16);z=1};
button3={cls="button";text="界面线程中获取数值";left=413;top=77;right=661;bottom=156;font=LOGFONT(h=-16);z=2};
button4={cls="button";text="其他线程中获取数值";left=413;top=202;right=661;bottom=281;font=LOGFONT(h=-16);z=3};
button5={cls="button";text="停止连续循环";left=71;top=171;right=319;bottom=235;z=4}
)
/*}}*/

import time.performance;
import console
console.open()
 
var struct_A = {float d[7500]={}};
var globalTab = raw.buffer(struct_A);
//初始化指针
var P_globalTab = raw.toPointer(globalTab);

//第一步设定指针
thread.set("全局线程结构体指针", P_globalTab);
 
winform.button2.oncommand = function(id,event){
    thread.set("手动停止", false);
    thread.invoke( 
        function(){
            import console
            import time.performance;
             
            var demo_B = {float d[7500]={}};
            //获取数据指针地址
            var P_Tab = thread.get("全局线程结构体指针");
            while(!thread.get("手动停止")){
                //模拟更新数据
                for(i=1;7500;1){
                    demo_B.d[i] = math.random();
                }
                var t1 = time.performance.tick();
                //数据复制到指针里
                raw.copy(P_Tab,demo_B);
                
                console.log("raw.copy(P_Tab,demo_B)耗时",time.performance.tick()-t1)
                console.log("连续线程中修改为demo_B.d[1]",demo_B.d[1]);
                console.log("连续线程中修改为demo_B.d[2]",demo_B.d[2]);
                 
                sleep(1000);//模拟一秒更新一次
            }
        }
    )
}
 
winform.button5.oncommand = function(id,event){
    //关闭模拟定时更新
    thread.set("手动停止", true);
}
 
winform.button3.oncommand = function(id,event){
    //界面线程中耗时比较大
    var t1=time.performance.tick();
    
    var demo_struct = raw.convert(P_globalTab,struct_A);
    console.log("界面线程中获取数值d[1]",demo_struct.d[1])
    console.log("界面线程中获取数值d[2]",demo_struct.d[2])
    
    console.log("界面线程中耗时比较大",time.performance.tick()-t1);
}
 
winform.button4.oncommand = function(id,event){
    //工作线程里操作耗时小
    thread.invoke( 
        function(){
            import console
            import time.performance;
            
            var t1=time.performance.tick();
            
            //获取数据指针地址
            var P_Tab = thread.get("全局线程结构体指针");
            //因为我的数据格式都是浮点型float, 所以有两种转换方式
/*          //第一种方式,直接转换为给定的结构体,适合于数据类型不相同的情况
            //要转换的结构体定义
            var struct_A = {float d[7500]={}};
            var demo1_struct = raw.convert(P_Tab,struct_A);
            console.log("其他线程中获取数值d[1]",demo1_struct.d[1])
            console.log("其他线程中获取数值d[2]",demo1_struct.d[2])
*/
            //第二种方式,转换为制定的数组float,适合于数据类型一致的情况
            var demo2_array = raw.convertArray(P_Tab,7500,"float");
            console.log("其他线程中获取数值d[1]",demo2_array[1])
            console.log("其他线程中获取数值d[2]",demo2_array[2])
            
            
            console.log("工作线程里操作耗时小",time.performance.tick()-t1);
        }
    )
}
 
winform.show();
win.loopMessage();





这里附上之前测试thread.table的代码 , 时间大概在21毫秒.

import console; 
console.open()

import time.performance;
var numA = {float d[7500]={}};
var struct_numA = {float d[7500]={}};
for(i=1;7500;1){
	numA.d[i]=math.random();
}
console.log("numA.d[1]",numA.d[1])
console.log("numA.d[2]",numA.d[2])
import thread.table;
var thrdTable = thread.table("线程共享表名称",true/*清空*/ );


//初始化并修改值
winform.button5.oncommand = function(id,event){
	var t1 = time.performance.tick()
	//混入表
	table.assign(thrdTable,numA.d)
	console.log("混入表耗时",time.performance.tick()-t1)
}

thread.table内部用到的仍然是thread.set() , 所以效率基本没变.

image.png

1 个回复 | 最后更新于 2021-05-13
2021-05-13   #1

登录后方可回帖

登 录
信息栏
公 告:

专注分享

谢绝纯提问

谢谢合作!
本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
打赏本站
Loading...