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

LabWindows?/CVI中的多线程技术

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

int CVICALLBACK ThreadFunction (void *functionData);
int tlvHandle;
int gSecondaryThreadTlvVal;

int main (int argc, char *argv[])
{
int functionId;
int *tlvPtr;

if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
CmtNewThreadLocalVar (sizeof(int), NULL, NULL, NULL, &tlvHandle);
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, 0, &functionId);
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
CmtGetThreadLocalVar (tlvHandle, &tlvPtr);
(*tlvPtr)++;
// Assert that tlvPtr has been incremented only once in this thread.
assert (*tlvPtr == gSecondaryThreadTlvVal);
CmtDiscardThreadLocalVar (tlvHandle);
return 0;
}
int CVICALLBACK ThreadFunction (void *functionData)
{
int *tlvPtr;

CmtGetThreadLocalVar (tlvHandle, &tlvPtr);
(*tlvPtr)++;
gSecondaryThreadTlvVal = *tlvPtr;
return 0;
}

11. 在线程局部变量中存储动态分配的数据

如果你使用线程局部变量来存储动态分配到的资源,那么你需要释放掉分配的资源的每一个拷贝。也就是说,你需要释放掉每个线程中分配到的资源拷贝。使用LabWindows/CVI的线程局部变量,你可以指定用于销毁线程局部变量的回调函数。当你销毁线程局部变量时,每个访问过变量的线程都会调用指定的回调函数。下面的代码展示了如何创建和访问保存了动态分配的字符串的线程局部变量。

int CVICALLBACK ThreadFunction (void *functionData);
void CVICALLBACK StringCreate (char *strToCreate);
void CVICALLBACK StringDiscard (void *threadLocalPtr, int event, void *callbackData, unsigned int threadID);
int tlvHandle;
volatile int quit = 0;
volatile int secondStrCreated = 0;

int main (int argc, char *argv[])
{
int functionId;

if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
CmtNewThreadLocalVar (sizeof(char *), NULL, StringDiscard, NULL, &tlvHandle);
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, "Secondary Thread", &functionId);
StringCreate ("Main Thread");
while (!secondStrCreated){
ProcessSystemEvents ();
Delay (0.001);
}
CmtDiscardThreadLocalVar (tlvHandle);
quit = 1;
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
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 ("Thread local string: %s\n", *sString);

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);
}

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

网站地图

Top