简体   繁体   English

DiscardAsyncTimer在计时器回调完成之前返回

[英]DiscardAsyncTimer returning before timer callback is complete

I'm trying to write a program in LabWindows/CVI 2017 using async timers but ran into a problem with the DiscardAsyncTimer() function. 我正在尝试使用异步计时器在LabWindows / CVI 2017中编写程序,但是遇到了DiscardAsyncTimer()函数的问题。 From the documentation for DiscardAsyncTimer(): 从DiscardAsyncTimer()的文档中:

A call to create or discard an asynchronous timer will not complete (will block) until all outstanding asynchronous callbacks return. 在所有未完成的异步回调返回之前,创建或放弃异步计时器的调用将不会完成(将阻塞)。

However, I ran into some memory problems where I was freeing memory used in my async timer thread after calling DiscardAsyncTimer(). 但是,在调用DiscardAsyncTimer()之后,我在释放异步计时器线程中使用的内存时遇到了一些内存问题。 I expected the memory to no longer be in use, but apparently this is not the case? 我希望不再使用该内存,但是显然不是这样吗? I have an example program below that recreates my problem. 我下面有一个示例程序,该程序重新创建了我的问题。 When run, this program generates a "general protection fault" due to trying to access freed memory. 运行时,此程序由于尝试访问释放的内存而生成“一般保护错误”。 However, if my understanding of the documentation, and the documentation itself, is correct, this should be impossible since DiscardAsyncTimer() is supposed to block until all callbacks return. 但是,如果我对文档以及文档本身的理解是正确的,那应该是不可能的,因为应该在所有回调返回之前阻塞DiscardAsyncTimer()。

My questions: 我的问题:

  1. Am I understanding the documentation correctly? 我是否正确理解文档?
  2. Am I doing something stupid in this example? 在这个例子中我在做些蠢事吗?
  3. How am I supposed to verify that my async timer threads have completed running before freeing the memory? 在释放内存之前,我应该如何验证我的异步计时器线程已完成运行?

Example program: 示例程序:

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

I also asked this question on the LabWindows/CVI forum a week ago without any response: https://forums.ni.com/t5/LabWindows-CVI/DiscardAsyncTimer-returning-before-timer-callback-is-complete/td-p/3943460 我还于一周前在LabWindows / CVI论坛上问了这个问题,没有任何回应: https : //forums.ni.com/t5/LabWindows-CVI/DiscardAsyncTimer-returning-before-timer-callback-is-complete/td- p / 3943460

I hadn't seen your question on the NI forum. 我在NI论坛上没有看到您的问题。 The quick answer is that async timers run in a separate thread, so you need to take the usual precautions. 快速的答案是异步计时器在单独的线程中运行,因此您需要采取通常的预防措施。 When the error occur you can see that with [Windows][Threads] and jump from one thread to the other. 发生错误时,您可以使用[Windows] [Threads]看到该错误,并从一个线程跳转到另一个线程。 Use a volatile variable for synchronisation, or better a semaphore. 使用易失性变量进行同步,或者更好地使用信号量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM