线程间传递比较大的结构数组的最佳方案
By
admin
at 2021-05-03 • 1人收藏 • 1322人看过
最近遇到个问题:
上次说到那个光纤分析仪的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
登录后方可回帖