События 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
выполняет работу в этом минимальном примере -
Определите класс, который будет источником события.
classdef bar < handle events sayhello end end
Создайте функцию, которая использует постоянную переменную
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 >>
Создайте другую функцию, которая использует глобальную переменную
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