Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

处理计时器队列冲突

在繁忙时段,在多执行情形中,计时器可能需要在先前排队的回调函数执行完毕之前,将计时器回调函数 (TimerFcn) 添加到 MATLAB® 执行队列中。您可以通过将 BusyMode 属性设置为以下模式之一来确定计时器对象如何处理此情形:

Drop 模式(默认值)

如果将 'drop' 指定为 BusyMode 属性的值,计时器对象仅在执行队列为空时才将计时器回调函数添加到该队列中。如果执行队列不为空,计时器对象会不执行回调。

例如,假设创建一个时间段为 1 秒的计时器,但其回调至少需要 1.6 秒,正如此处 mytimer.m 所示的计时器。

function mytimer()
    t = timer;

    t.Period         = 1;
    t.ExecutionMode  = 'fixedRate';
    t.TimerFcn       = @mytimer_cb;
    t.BusyMode       = 'drop';
    t.TasksToExecute = 5;
    t.UserData       = tic;

    start(t)
end


function mytimer_cb(h,~)
    timeStart = toc(h.UserData)
    pause(1.6);
    timeEnd = toc(h.UserData)
end

下表介绍了该计时器管理执行队列的方式。

所耗的大致时间(秒)

操作

0

开始首次执行回调。

1

尝试开始第二次执行回调。第一次执行未完毕,但执行队列为空。计时器将回调添加到队列中。

1.6

第一次执行回调完毕,并开始第二次。此操作会清除执行队列。

2

尝试开始第三次执行回调。第二次执行未完毕,但该队列为空。计时器将回调添加到队列中。

3

尝试开始第四次执行回调。第三次回调在执行队列中,因此计时器此次放弃执行函数。

3.2

第二次执行回调完毕并开始第三次,并且清除执行队列。

4

尝试开始再一次执行回调。因为队列为空,所以计时器将回调添加到队列中。这是第五次尝试,但仅运行第四个实例。

4.8

第三次执行回调完毕并开始第四个实例,并且清除队列。

5

尝试开始再一次回调。某个实例正在运行,但执行队列为空,因此计时器将其添加到队列中。这是将运行的第五个实例。

6

不执行任何操作:TasksToExecute 属性的值是 5,要运行的第五个实例在队列中。

6.4

第四次执行回调完毕并开始第五次。

8

第五次执行回调完毕。

错误模式

BusyMode 属性的 'error' 模式类似于 'drop' 模式:在这两种模式下,计时器仅允许执行队列中有一个回调实例。但在 'error' 模式下,当队列不为空时,计时器会调用您使用 ErrorFcn 属性指定的函数,然后停止处理。当前运行的回调函数执行完毕,但不执行队列中的回调。

例如,修改 mytimer.m(上一节中所述)以使其包含错误处理函数并将 BusyMode 设置为 'error'

function mytimer()
    t = timer;

    t.Period         = 1;
    t.ExecutionMode  = 'fixedRate';
    t.TimerFcn       = @mytimer_cb;
    t.ErrorFcn       = @myerror;
    t.BusyMode       = 'error';
    t.TasksToExecute = 5;
    t.UserData       = tic;

    start(t)
end


function mytimer_cb(h,~)
    timeStart = toc(h.UserData)
    pause(1.6);
    timeEnd = toc(h.UserData)
end

function myerror(h,~)
    disp('Reached the error function')
end

下表介绍了该计时器管理执行队列的方式。

所耗的大致时间(秒)

操作

0

开始首次执行回调。

1

尝试开始第二次执行回调。第一次执行未完毕,但执行队列为空。计时器将回调添加到队列中。

1.6

第一次执行回调完毕,并开始第二次。此操作会清除执行队列。

2

尝试开始第三次执行回调。第二次执行未完毕,但该队列为空。计时器将回调添加到队列中。

3

尝试开始第四次执行回调。第三次回调在执行队列中。计时器不执行第三次回调,而是调用错误处理函数。

3.2

第二次回调执行完毕并启动错误处理函数。

Queue 模式

如果您指定 'queue',则计时器对象会一直等到当前执行的回调函数执行完毕,然后才再次排队执行计时器回调函数。

'queue' 模式下,计时器对象会尝试使每次执行之间的平均时间等于 Period 属性中指定的时间量。如果计时器对象必须等待的时间比 Period 属性中指定的每次执行计时器函数回调之间的时间更长,则它会缩短该时间段以便后续执行弥补这段时间。

另请参阅

相关主题