События Matlab и слушатели: распространять информацию из вызова Event

У меня есть объект, который включает в себя событие, которое создается в моей программе (в частности, основанный на сеансе ni daq с событием "DataAvailable", которое запускается каждый раз, когда получено заданное количество выборок.) Это событие будет запускаться случайным образом в течение курс запуска моей программы, которая будет делать другие вещи независимо от записи. Когда запущено, это соберет и сохранит порцию данных в файл.

Моя проблема в том, что каждый раз, когда событие запускается, мне нужно увеличивать счетчик (я называю его "чанк") в моей исходной программе. Это очень важно, так как ряд функций в моей программе зависит от моей способности точно измерить количество фрагментов.

ВОПРОС: как я могу распространить факт, что событие было вызвано в моей основной программе?

Для людей, которые лучше обрабатывают (псевдо) код:

setupStuff();
endLoop = false;
while ~endLoop
  if ~recording
    session  = createDAQSessionObject(params);
    chunkNum = 0;
    session.addListener('DataAvailable',@(src,event)saveChunk(src,event,chunkNum));
    session.startBackGround()
    recording  = true;
  end
  endLoop = doOtherStuff();
  pause(0.1);
end

function saveChunk(src,event,numChunk)
  filename = sprintf('chunk%d.mat',numChunk);
  times = event.TimeStamps;
  data = event.Data;
  save(filename,'times','data');
  % but now the next time around we need to get in numChunks+1 (but we never will because we have no way of knowing that the event was called...
end

Спасибо

-bas

1 ответ

С помощью global или же persistent выполняет работу в этом минимальном примере -

  1. Определите класс, который будет источником события.

    classdef bar < handle
        events
            sayhello
        end
    end
    
  2. Создайте функцию, которая использует постоянную переменную num, num виден только для функции foo, но это "постоянный" между вызовами foo, Остается в foo Рабочая область до clear all или Matlab выходит.

    function foo(~,~)
    persistent num
    if isempty(num)
        num = 1;
    else
        num = num+1;
    end
    fprintf('hi %d\n', num);
    end
    

    .... и вызвать его из основного скрипта

    bigjob = bar;
    addlistener(bigjob, 'sayhello', @foo);
    
    for ii = 1:10
        notify(bigjob, 'sayhello')
    end
    

    Выход:

    hi 1
    hi 2
    hi 3
    hi 4
    hi 5
    hi 6
    hi 7
    hi 8
    hi 9
    hi 10
    >> 
    
  3. Создайте другую функцию, которая использует глобальную переменную num, num хранится в базовой рабочей области, виден всем функциям, а также основному сценарию и действует до clear global num называется или Matlab выходит.

    function foo(~,~)
    global num
    num = num+1;
    fprintf('hi %d\n', num);
    end
    

    .... и измените скрипт для объявления и инициализации глобального num

    global num
    num = 0;
    bigjob = bar;
    addlistener(bigjob, 'sayhello', @foo);
    
    for ii = 1:10
        notify(bigjob, 'sayhello')
    end
    

    Выход:

    hi 1
    hi 2
    hi 3
    hi 4
    hi 5
    hi 6
    hi 7
    hi 8
    hi 9
    hi 10
    >> 
    

Проблемы эффективности

С помощью global или же persistent это дорого Я изменил свой код на ii = 50000 и заглушил fprintf, чтобы выполнить тест.

Согласно Profiler, используя global занимает ~10% от общего времени работы; используя global "Я имею в виду декларирование global num в функции foo,

.... при использовании persistent занимает ~25% от общего времени работы (это в сумме составляет persistent медленнее, чем global); используя persistent "Я имею в виду эти строки

persistent num
if isempty(num)
else
end
Другие вопросы по тегам