c语言sscanf函数的用法是什么
243
2022-11-02
利用线程局部存储技术实现全局变量局部化的多通道数控系统仿真
1 概述
COM 在STA 套间内的线程中创建一个隐藏窗口,将套间外的线程对这个对象的调用都转变成对隐藏窗口发送消息,并由隐藏窗口的消息处理函数来实际调用组件对象,从而实现STA 套间模型。
一个进程中的所有线程均处于同一虚拟地址空间,每个函数的局部变量在运行该函数的每个线程中都是唯一的,但静态和全局变量则被所有线程所共享。即在多个ActiveX 组件实例的情况下,ActiveX 组件的 STA 模型不能保证全局数据成员是线程安全的。
2 线程局部存储原理
线程局部存储(Thread Local Storage, TLS)是Win32 系统提供的一种简化多线程程序设计的底层基础技术,其实质是介入全局数据创建过程,建立并管理全局数据与线程的关联,使得全局数据为其关联线程所私有。TLS 原理如图1 所示。
每个进程拥有一组TLS 槽口(Slot),每个槽口用序号标识,Windows 2000 有1 088 个这样的槽口。线程通过API 函数可以分配TLS 槽口,在TLS 槽口存取数据,进程中使用同一个序号的不同线程可指向独立的局部堆内存中进行数据存储,即线程ID 和槽口号确定了一个二维空间映射,线程通过API 函数获得线程间相互独立的数据存储地址。
图 1 也表明了采用TLS 机制的具有2 个ActiveX 组件实例的运行时软件内存结构,进程分配了2 个TLS 索引值gdwTlsIndex1 和 gdwTlsIndex2,这2 个索引值代表了TLS槽口的序号,但不同线程按照相同的序号却得到2 个独立的局部堆地址,而这些数据在线程内却具有全局数据的可访问性,即每个线程有单独的全局数据拷贝,该数据对线程内的函数具有全局作用域。
Win32 系统中与TLS 有关的API 及用法如下:
(1)进程初始化时分配TLS 槽口:
DWORD gdwTlsIndex;gdwTlsIndex = TlsAlloc();
(2)调用TlsSetValue 保存数据:
LPVOID lpvBuffer;lpvBuffer = (LPVOID) LocalAlloc(LPTR, 256);
TlsSetValue(gdwTlsIndex, lpvBuffer); //保存存储区指针
(3)调用TlsGetValue 取数据:
LPVOID lpvData;lpvData = TlsGetValue(gdwTlsIndex); //取TLS 槽口中保存的存//储区指针
(4)调用TlsFree 释放槽口:
lpvBuffer = TlsGetValue(gdwTlsIndex);
LocalFree((HLOCAL) lpvBuffer); //释放存储区
TlsFree(gdwTlsIndex); //释放TLS 槽口
3 应用实例
可见,显示缓存等核心数据结构设计为全局变量,但HNC-32 的设计目标是多通道数控系统,每个通道都需要一个实体加工仿真组件的实例,由于全局缓存数据为所有实例共享,因此出现的所有通道显示内容将完全一致,无法实现多通道仿真。为简化改造工作,将原系统中约50 多个全局变量合并为一个结构,并将原全局变量作为其成员,即一个大的结构变量包括了50 个原全局变量。
在其他函数中,可以通过线程索dwTlsIndex 调用API函数TlsGetValue 引访问到上述大结构变量,进而访问到原全局变量,代码如下:
//被OpenPatg-》hFile 调用读刀位文件并显示刀位轨迹
GlobalValues *g=(GlobalValues *)TlsGetValue(dwTlsIndex);
g-》CtrlObj-》GetClientRect(&rt);。..
应用实例界面如图 2 所示。
在 TLS 改造后,每个ActiveX 实例均有单独的、与线程索引对应的局部堆全局变量,各个通道运行不同的代码程序并在各自通道的实体仿真上显示各自的运行结果,实现了多通道的独立执行。
4 结束语
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~