关于Labwindows的多线程技术 联系客服

发布时间 : 星期六 文章关于Labwindows的多线程技术更新完毕开始阅读4b70c40c7cd184254b35356c

return 0; } int CVICALLBACK ThreadFunction (void *functionData) { char **sString; // Create thread local string variable StringCreate ((char *)functionData); // Get thread local string and print it CmtGetThreadLocalVar (tlvHandle, &sString); printf (\ secondStrCreated = 1; while (!quit) { ProcessSystemEvents (); Delay (0.001); } return 0; } void CVICALLBACK StringCreate (char *strToCreate) { char **tlvStringPtr; CmtGetThreadLocalVar (tlvHandle, &tlvStringPtr); *tlvStringPtr = malloc (strlen (strToCreate) + 1); strcpy (*tlvStringPtr, strToCreate); } void CVICALLBACK StringDiscard (void *threadLocalPtr, int event, void *callbackData, unsigned int threadID) { char *str = *(char **)threadLocalPtr; free (str); } 一些分配的资源必须在分配到它们的线程中释放。这些资源被称为拥有线程关联度。例如,面板必须在创建它的线程中销毁掉。在调用

CmtDiscardThreadLocalVar时,Utility Library在线程中调用被称为

CmtDiscardThreadLocalVar的线程局部变量销毁回调函数。Utility Library为每一个访问过该变量的线程调用一次销毁回调函数。它将threadID参数传递给销毁回调函数,这个参数指定了调用销毁回调函数的线程的ID号。你可以使用这个线程ID来确定是否可以直接释放掉拥有线程关联度的资源还是必须在正

确的线程中调用Toolslib中的 PostDeferredCallToThreadAndWait函数来释放资源。下面的代码显示了如何更改前面的例子以在分配字符串的线程中将它们释放掉。

void CVICALLBACK StringDiscard (void *threadLocalPtr, int event, void *callbackData, unsigned int threadID) { char *str = *(char **)threadLocalPtr; if (threadID == CmtGetCurrentThreadID ()) free (str); else PostDeferredCallToThreadAndWait (free, str, threadID, POST_CALL_WAIT_TIMEOUT_INFINITE); } 在独立线程中运行的回调函数

使用LabWindows/CVI中的一些库,你可以在系统创建的线程中接收回调函数。因为这些库会自动创建执行回调函数的线程,所以你不需要创建线程或者将函数调度到单独的线程中执行。在程序中,你仍然需要对这些线程和其它线程间共享的数据进行保护。这些回调函数的实现通常被称为是异步事件。

LabWindows/CVI的GPIB/GPIB 488.2库中,可以调用ibnotify来注册事件发生时GPIB/GPIB 488.2库调用的回调函数。你可以为每一个电路板或器件指定一个回调函数。可以为事件指定调用的回调函数。GPIB/GPIB 488.2库会创建用于执行回调函数的线程。

在LabWindows/CVI的虚拟仪器软件构架 (VISA) 库中,你可以调用viInstallHandler函数来注册多个事件句柄(回调函数)用于在特定的

ViSession 中接收VISA事件(I/O完成、服务请求等等)类型。VISA库通常创建独立的线程来执行回调函数。VISA可能会对一个进程中的所有回调函数使用同一个线程,或者对每个ViSession 使用单独的线程。你需要为某个指定的事件类型调用viEnableEvent函数以通知VISA库调用已注册的事件句柄。 在LabWindows/CVI VXI库中,每个中断或回调函数类型都有自己的回调注册和使能函数。例如,为了接收NI-VXI中断,你必须调用SetVXIintHandler和EnableVXIint函数。VXI库使用自己创建的独立线程来执行回调函数。对于同一进程中所有的回调函数,VXI都使用相同的线程。

为线程设定首选的处理器

可以使用平台SDK中的SetThreadIdealProcessor函数来指定执行某一线程的处理器。这个函数的第一个参数是线程句柄。第二个参数是以零为索引起始的处理器。可以调用LabWindows/CVI Utility Library中的CmtGetThreadPoolFunctionAttribute函数,使用

ATTR_TP_FUNCTION_THREAD_HANDLE属性来获取线程池线程的句柄。可以调用LabWindows/CVI Utility Library中的CmtGetNumberOfProcessors函数来通过程序来确定运行该程序的计算机上处理器的数量。

可以使用平台SDK中的SetProcessAffinityMask函数来指定允许执行你的程序的处理器。可以使用平台SDK中的SetThreadAffinityMask函数来指定允许执行程序中特定线程的处理器。传递到SetThreadAffinityMask中的mask变量必须是传递到SetProcessAffinityMask中的mask变量的子集。

这些函数只有程序在装有Microsoft Windows XP/2000/NT 4.0系统的多处理器计算机上运行才有效果。Microsoft Windows 9x系列的操作系统不支持多处理器计算机。