DiscardAsyncTimer 在计时器回调完成之前返回
DiscardAsyncTimer returning before timer callback is complete
我试图在 LabWindows/CVI 2017 年使用异步计时器编写一个程序,但 运行 遇到了 DiscardAsyncTimer() 函数的问题。来自 DiscardAsyncTimer() 的文档:
A call to create or discard an asynchronous timer will not complete
(will block) until all outstanding asynchronous callbacks return.
但是,我 运行 遇到了一些内存问题,我在调用 DiscardAsyncTimer() 后释放了异步计时器线程中使用的内存。我预计内存不再被使用,但显然情况并非如此?我在下面有一个示例程序可以重现我的问题。当 运行 时,此程序由于试图访问已释放的内存而生成 "general protection fault"。但是,如果我对文档和文档本身的理解是正确的,那么这应该是不可能的,因为 DiscardAsyncTimer() 应该阻塞直到所有回调 return.
我的问题:
- 我对文档的理解是否正确?
- 我在这个例子中做错了什么吗?
- 在释放内存之前,我应该如何验证我的异步计时器线程是否已完成 运行ning?
示例程序:
#include <ansi_c.h>
#include <asynctmr.h>
#include <stdio.h>
#include <utility.h>
#include <userint.h>
typedef struct {
int* array;
} MyStruct;
int CVICALLBACK ShuffleValues (int reserved, int timerId, int event, void *callbackData, int eventData1, int eventData2)
{
if (event == EVENT_TIMER_TICK) {
printf("start\n");
MyStruct* mystruct = callbackData;
// Shuffle values
for(int i = 0;i < 1000;i++) {
mystruct->array[0] = mystruct->array[1];
mystruct->array[1] = mystruct->array[2];
Delay(0.01);
}
printf("finished\n");
}
return 0;
}
int main ()
{
// Allocate memory
MyStruct* mystruct = malloc(sizeof(MyStruct));
mystruct->array = malloc(10 * sizeof(int));
// Start Async Timer
int timer = NewAsyncTimer(0.01, -1, 1, ShuffleValues, mystruct);
// Wait a while to let the timer thread run a bit
Delay(0.5);
// Destroy Async Timer
printf("start destroying\n");
int retval = DiscardAsyncTimer(timer);
printf("finished destroying: %d\n", retval);
// Free memory now that the timer thread is no longer running
free(mystruct->array);
free(mystruct);
Delay(1);
return 0;
}
我一周前也在LabWindows/CVI论坛上问过这个问题,没有任何回复:https://forums.ni.com/t5/LabWindows-CVI/DiscardAsyncTimer-returning-before-timer-callback-is-complete/td-p/3943460
我没有在 NI 论坛上看到你的问题。快速的回答是异步定时器 运行 在一个单独的线程中,所以你需要采取通常的预防措施。
发生错误时,您可以使用 [Windows][Threads] 看到错误并从一个线程跳转到另一个线程。
使用 volatile 变量进行同步,或者更好的信号量。
我试图在 LabWindows/CVI 2017 年使用异步计时器编写一个程序,但 运行 遇到了 DiscardAsyncTimer() 函数的问题。来自 DiscardAsyncTimer() 的文档:
A call to create or discard an asynchronous timer will not complete (will block) until all outstanding asynchronous callbacks return.
但是,我 运行 遇到了一些内存问题,我在调用 DiscardAsyncTimer() 后释放了异步计时器线程中使用的内存。我预计内存不再被使用,但显然情况并非如此?我在下面有一个示例程序可以重现我的问题。当 运行 时,此程序由于试图访问已释放的内存而生成 "general protection fault"。但是,如果我对文档和文档本身的理解是正确的,那么这应该是不可能的,因为 DiscardAsyncTimer() 应该阻塞直到所有回调 return.
我的问题:
- 我对文档的理解是否正确?
- 我在这个例子中做错了什么吗?
- 在释放内存之前,我应该如何验证我的异步计时器线程是否已完成 运行ning?
示例程序:
#include <ansi_c.h>
#include <asynctmr.h>
#include <stdio.h>
#include <utility.h>
#include <userint.h>
typedef struct {
int* array;
} MyStruct;
int CVICALLBACK ShuffleValues (int reserved, int timerId, int event, void *callbackData, int eventData1, int eventData2)
{
if (event == EVENT_TIMER_TICK) {
printf("start\n");
MyStruct* mystruct = callbackData;
// Shuffle values
for(int i = 0;i < 1000;i++) {
mystruct->array[0] = mystruct->array[1];
mystruct->array[1] = mystruct->array[2];
Delay(0.01);
}
printf("finished\n");
}
return 0;
}
int main ()
{
// Allocate memory
MyStruct* mystruct = malloc(sizeof(MyStruct));
mystruct->array = malloc(10 * sizeof(int));
// Start Async Timer
int timer = NewAsyncTimer(0.01, -1, 1, ShuffleValues, mystruct);
// Wait a while to let the timer thread run a bit
Delay(0.5);
// Destroy Async Timer
printf("start destroying\n");
int retval = DiscardAsyncTimer(timer);
printf("finished destroying: %d\n", retval);
// Free memory now that the timer thread is no longer running
free(mystruct->array);
free(mystruct);
Delay(1);
return 0;
}
我一周前也在LabWindows/CVI论坛上问过这个问题,没有任何回复:https://forums.ni.com/t5/LabWindows-CVI/DiscardAsyncTimer-returning-before-timer-callback-is-complete/td-p/3943460
我没有在 NI 论坛上看到你的问题。快速的回答是异步定时器 运行 在一个单独的线程中,所以你需要采取通常的预防措施。 发生错误时,您可以使用 [Windows][Threads] 看到错误并从一个线程跳转到另一个线程。 使用 volatile 变量进行同步,或者更好的信号量。