DiscardAsyncTimer возвращается до завершения обратного вызова таймера - PullRequest
0 голосов
/ 07 июля 2019

Я пытаюсь написать программу в LabWindows / CVI 2017 с использованием асинхронных таймеров, но столкнулся с проблемой с функцией DiscardAsyncTimer (). Из документации по DiscardAsyncTimer ():

Вызов для создания или отмены асинхронного таймера не будет завершен (будет блокироваться), пока не будут возвращены все ожидающие асинхронные обратные вызовы.

Однако я столкнулся с некоторыми проблемами с памятью, когда я освобождаю память, используемую в моем потоке асинхронного таймера после вызова DiscardAsyncTimer (). Я ожидал, что память больше не будет использоваться, но, видимо, это не так? У меня есть пример программы ниже, которая воссоздает мою проблему. При запуске эта программа генерирует «общую ошибку защиты» из-за попытки доступа к освобожденной памяти. Однако, если мое понимание документации и самой документации правильное, это должно быть невозможно, поскольку DiscardAsyncTimer () должен блокироваться до тех пор, пока не будут возвращены все обратные вызовы.

Мои вопросы:

  1. Правильно ли я понимаю документацию?
  2. Я делаю что-то глупое в этом примере?
  3. Как я должен проверить, что мои потоки асинхронного таймера завершили работу перед освобождением памяти?

Пример программы:

#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

...