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

LabWindows?/CVI中的多线程技术

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

释放掉这些线程锁,让线程2在晚些时候获取到。就像上面所说的那样,死锁现象只有在线程同时获取线程锁时才会发生。所以你可以使用简单的规则来避免这种死锁。当需要获取多个线程锁对象时,程序中的每个线程都需要按照相同的顺序来获取线程锁对象。下面的LabWindows/CVI Utility Library函数获取线程锁对象,并且返回时并不释放这些对象。

  • CmtGetLock
  • CmtGetTSQReadPtr
  • CmtGetTSQWritePtr

注意事项:通常说来,不需要直接调用CmtGetTSVPtr函数。它是通过DeclareThreadSafeVariable宏创建的GetPtrToVarName函数调用的。因此,对于调用的GetPtrToVarName函数需要将它作为线程锁对象获取函数来对待,应该注意死锁保护的问题。
The following Windows SDK functions can acquire thread-locking objects without releasing them before returning.Note:This is not a comprehensive list.

下面的Windows SDK函数可以获取线程锁对象但在返回时并不释放这些对象。注意,这不是完整的列表。

  • EnterCriticalSection
  • CreateMutex
  • CreateSemaphore
  • SignalObjectAndWait
  • WaitForSingleObject
  • MsgWaitForMultipleObjectsEx

7. 监视和控制辅助线程

在把一个函数调度到独立的线程中运行时,需要对被调度函数的运行状态进行监视。为了获得被调度函数的运行状态,调用CmtGetThreadPoolFunctionAttribute来获得ATTR_TP_FUNCTION_EXECUTION_STATUS属性的值。也可以注册一个回调函数,线程池调用之后立即运行被调度的函数和/或开始运行后立即由线程池调用。如果需要注册这样的回调函数,必须使用CmtScheduleThreadFunctionAdv来对函数进行调度。

通常说来,辅助进程需要在主线程结束程序前完成。如果主线程在辅助线程完成之前结束,那么辅助线程将不能够将分配到的资源清理掉。同时,可能导致这些辅助线程所使用的库函数也不能被正确清除。

可以调用CmtWaitForThreadPoolFunctionCompletion函数来安全地等待辅助线程结束运行,然后允许主线程结束。

在一些例子中,辅助线程函数必须持续完成一些工作直到主线程让它停止下来。在这类情况下,辅助线程通常在while循环中完成任务。while循环的条件是主线程中设定的整数变量,当主线程需要告知辅助线程停止运行时,将其设为非零整数。下面的代码显示了如何使用while循环来控制辅助线程何时结束执行。

volatile int quit = 0;

int main (int argc, char *argv[])
{
int functionId;
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &functionId);
// This would typically be done inside a user interface
// Quit button callback.
quit = 1;
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
return 0;
}
int CVICALLBACK ThreadFunction (void *functionData)
{
while (!quit) {
. . .
}
return 0;
}

注意事项:如果使用volatile关键字,这段代码在经过优化的编译器(如Microsoft Visual C++)后功能是正常的。优化的编译器确定while循环中的代码不会修改quit变量的值。因此,作为优化,编译器可能只使用quit变量在while循环条件中的初始值。使用volatile关键字是告知编译器另一个线程可能会改变quit变量的值。这样,编译器在每次循环运行时都使用更新过后的quit变量值。

有些时候,当主线程进行其他任务的时候需要暂停辅助线程的运行。如果你暂停正在运行操作系统代码的线程,可能会使得操作系统处于非法状态。因此,在需要暂停的线程中需要始终调用Windows SDK的SuspendThreadfunction函数。这样,可以确保线程在运行关键代码时不被暂停。在另一个线程中调用Windows SDK的ResumeThreadfunction是安全的。下面的代码展示了如何使用它们。

volatile int quit = 0;

int main (int argc, char *argv[])
{
int functionId;
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &functionId);
// This would typically be done inside a user interface
// Quit button callback.
quit = 1;
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
return 0;
}
int CVICALLBACK ThreadFunction (void *functionData)
{
while (!quit) {
. . .
}
return 0;
}

8. 进程和线程优先级

在Windows操作系统中,可以指定每个进程和线程工作的相对重要性(被称为优先级)。如果给予进程或线程以较高的优先级,那么它们将获得比优先级较低的线程更好的优先选择。这意味着当多个线程需

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

网站地图

Top