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

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

最近遇到个问题:

上次说到那个光纤分析仪的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

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...