1

我有一个对象,它包含在我的程序中创建的事件(具体来说,一个基于会话的 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

4

1 回答 1

3

Using global or persistent does the job in this minimal example -

  1. Define a class to be the event source.

    classdef bar < handle
        events
            sayhello
        end
    end
    
  2. Build a function that uses a persistent variable num. num is visible only to function foo, but it is "persistent" between calls to foo. It remains in foo's workspace until clear all is excecuted, or Matlab quits.

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

    .... and call it from main script

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

    Output:

    hi 1
    hi 2
    hi 3
    hi 4
    hi 5
    hi 6
    hi 7
    hi 8
    hi 9
    hi 10
    >> 
    
  3. Build another function that uses a global variable num. num is kept in base workspace, visible to all functions as well as the main script, and is alive until clear global num is called or Matlab quits.

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

    .... and change the script to declare and initialize the global num

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

    Output:

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

Efficiency concerns

Using global or persistent is costly. I changed my code to ii = 50000, and muted the fprintf, to perform a benchmark.

According to Profiler, using global takes ~10% of total running time; by "using global" I mean declaring global num in function foo.

.... while using persistent takes ~25% of total running time (it adds up to the total, so running persistent is slower than global); by "using persistent" I mean these lines

persistent num
if isempty(num)
else
end
于 2014-08-13T07:06:30.683 回答