线程间传递比较大的结构数组的最佳方案
By
admin
at 2021-05-03 • 1人收藏 • 1424人看过
最近遇到个问题:
上次说到那个光纤分析仪的dll里会返回一个结构体 , 内部有两个记录了7500个位置的数组,
需要在一个线程里连续读取这个dll的返回数组, 然后更新并返回给其他线程使用.
之前用thread.set("pos1",table_A)来传递到其他线程, 测试结果发现这句话需要执行30毫秒左右,然后我换成thread.table, 执行结果20毫秒左右,感觉这种方式效率比较低, 那么有没有其他方式?
经过我的各种测试,最终得出的结论如下:
答案:使用raw.copy()直接操作指针. 时间基本上在1ms以内了.

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() , 所以效率基本没变.

1 个回复 | 最后更新于 2021-05-13
jacen_he
2021-05-13
#1
登录后方可回帖