微波EDA网,见证研发工程师的成长!
首页 > 测试测量 > 测试测量技术文库 > LabWindows?/CVI中的多线程技术

LabWindows?/CVI中的多线程技术

时间:12-23 来源:互联网 点击:

只允许一个线程获得特定的线程锁对象。一旦线程调用操作系统API函数试图获取另一个线程正在持有的线程锁对象,那么试图获取线程锁对象的线程回在操作系统API获取函数中等待,直到拥有线程锁对象的线程将它释放掉后才返回。试图获取其它线程持有的线程锁对象的线程被称为阻塞线程。LabWindows/CVI Utility Library提供了三种保护数据的机制:线程锁、线程安全变量和线程安全队列。

线程锁对操作系统提供的简单的线程锁对象进行了封装。在三种情况下,你可能要使用到线程锁。如果有一段需要访问多个共享数据变量的代码,那么在运行代码前需要获得线程锁,而在代码运行后释放线程锁。与对每段数据都进行保护相比,这个方法的好处是代码更为简单,而且不容易出错。缺点是减低了性能,因为程序中的线程持有线程锁的时间可能会比实际需要的时间长,这会造成其它线程为获得线程锁而阻塞(等待)的时间变长。使用线程锁的另一种情况是需要对访问非线程安全的第三方库函数时进行保护。例如,有一个非线程安全的DLL用于控制硬件设备而你需要在多个线程中调用这个DLL,那么可以在线程中调用DLL前创建需要获得的线程锁。第三种情况是,你需要使用线程锁来保护多个程序间共享的资源。共享内存就是这样一种资源。

线程安全变量技术将操作系统的线程锁对象和需要保护的数据结合起来。与使用线程锁来保护一段数据相比,这种方法更为简单而且不容易出错。你必须使用线程安全变量来保护所有类型的数据,包括结构体类型。线程安全变量比线程锁更不容易出错,是因为用户需要调用Utility Library API函数来访问数据。而API函数获取操作系统的线程锁对象,避免用户不小心在未获取OS线程锁对象的情况下对数据进行访问的错误。线程安全变量技术比线程锁更简单,因为用户只需要使用一个变量(线程安全变量句柄),而线程锁技术则需要使用两个变量(线程锁句柄和需要保护的数据本身)。

线程安全队列是一种在线程间进行安全的数组数据传递的机制。在程序中有一个线程生成数组数据而另外一个线程对数组数据进行处理时,需要使用线程安全队列。这类程序的一个例子就是在一个线程中采集数据,而在另一个线程中分析数据或者将数据显示在LabWindows/CVI的用户界面上。与一个数组类型的线程安全变量相比,线程安全队列有着如下的优势:

  • 线程安全队列在其内部使用了一种锁策略,一个线程可以从队列读取数据而同时另一个线程向队列中写入数据(例如,读取和写入线程不会互相阻塞)。
  • 用户可以为基于事件的访问配置线程安全队列。用户可以注册一个读取回调函数,在队列中有一定数量的数据可用时,调用这个函数,并且/或者注册一个写入回调函数,在队列中有一定的空间可用时,调用这个函数。
  • 用户可以对线程安全队列进行配置,使得在数据增加而空间已满时,队列可以自动生长。

线程锁技术

在程序初始化的时候,调用CmtNewLock函数来为每个需要保护的数据集合创建线程锁。这个函数返回一个句柄,用户可以使用它在后续的函数调用中指定线程锁。在访问由锁保护的数据和代码前,线程必须调用CmtGetLock函数来获取线程锁。在访问数据后,线程必须调用CmtReleaseLock函数来释放线程锁。在同一个线程中,可以多次调用CmtGetLock(不会对后续调用产生阻塞),但是用户每一次调用CmtGetLock都需要调用一次CmtReleaseLock来释放。在程序退出时,调用CmtDiscardLock函数来释放线程锁资源。下面的代码演示了如何使用LabWindows/CVI Utility Library中的线程锁来保护全局变量。

int lock;
int count;

int main (int argc, char *argv[])
{
int functionId;
CmtNewLock (NULL, 0, &lock);
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &functionId);
CmtGetLock (lock);
count++;
CmtReleaseLock (lock);
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
CmtDiscardLock (lock);
}
int CVICALLBACK ThreadFunction (void *functionData)
{
CmtGetLock(lock);
count++;
CmtReleaseLock(lock);
return 0;
}

线程安全变量

线程安全变量技术将数据和操作系统线程锁对象结合成为一个整体。这个方法避免了多线程编程中一个常见的错误:程序员在访问变量时往往忘记首先去获得锁。这种方法还使得在函数间传递保护的数据变得容易,因为只需要传递线程安全变量句柄而不需要既传递线程锁句柄又要传递保护的变量。LabWindows/CVI Utility Library API中包含了几种用于创建和访问线程安全变量的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top