Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

タイマー キューの競合への対処

複数実行のシナリオにおけるビジー時間では、タイマーは、コールバック関数の前のキューにある実行が終了する前に、タイマー コールバック関数 (TimerFcn) を MATLAB® の実行キューに追加しなければならない場合があります。timer オブジェクトで、次のいずれかのモードを使用するように BusyMode プロパティを設定して、このシナリオを扱う方法を決定できます。

ドロップ モード (既定)

BusyMode プロパティの値として 'drop' を指定する場合、timer オブジェクトは、キューが空の場合のみにタイマー コールバック関数を実行キューに追加します。実行キューが空でない場合、timer オブジェクトはコールバックの実行をスキップします。

たとえば、この mytimer.m に示されるように、1 秒間隔のタイマーを作成するがコールバックで少なくとも 1.6 秒必要であるとします。

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

コールバックの 2 番目の実行の開始を試みます。最初の実行は完了していませんが、実行キューは空です。タイマーは、コールバックをキューに追加します。

1.6

最初のコールバックの実行を終了して、2 番目を開始します。このアクションにより、実行キューがクリアされます。

2

3 番目のコールバックの実行の開始を試みます。2 番目の実行は完了していませんが、キューは空です。タイマーは、コールバックをキューに追加します。

3

4 番目のコールバックの実行の開始を試みます。3 番目のコールバックが実行キューにあるので、タイマーはこの関数の実行を棄却します。

3.2

2 番目のコールバックを終了して、3 番目を開始し、実行キューをクリアします。

4

別のコールバックの実行の開始を試みます。キューは空であるため、タイマーはコールバックをキューに追加します。これは 5 番目の試行ですが、4 番目のインスタンスのみが実行されます。

4.8

3 番目の実行を終了して、4 番目のインスタンスを開始し、実行キューをクリアします。

5

別のコールバックの開始を試みます。インスタンスは実行中ですが、キューが空であるため、タイマーはそれをキューに追加します。これが、実行される 5 番目のインスタンスです。

6

何もしません。TasksToExecute プロパティの値は 5 であり、実行する 5 番目のインスタンスはキューの中にあります。

6.4

4 番目のコールバックの実行を終了して、5 番目を開始します。

8

5 番目のコールバックの実行を終了します。

エラー モード

BusyMode プロパティの 'error' モードは、'drop' モードと同様です。両方のモードとも、タイマーは実行キューのコールバックのインスタンスを 1 つのみ使用できます。ただし、'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

コールバックの 2 番目の実行の開始を試みます。最初の実行は完了していませんが、実行キューは空です。タイマーは、コールバックをキューに追加します。

1.6

最初のコールバックの実行を終了して、2 番目を開始します。このアクションにより、実行キューがクリアされます。

2

3 番目のコールバックの実行の開始を試みます。2 番目の実行は完了していませんが、キューは空です。タイマーは、コールバックをキューに追加します。

3

4 番目のコールバックの実行の開始を試みます。3 番目のコールバックは実行キューの中にあります。タイマーは 3 番目のコールバックを実行しませんが、代わりにエラー処理関数を呼び出します。

3.2

2 番目のコールバックを終了して、エラー処理関数を開始します。

キュー モード

'queue' を指定すると、timer オブジェクトは、タイマー コールバック関数の次の実行をキューに入れる前に、現在の実行コールバック関数が終了するまで待機します。

'queue' モードでは、timer オブジェクトは実行間の平均時間を Period プロパティに指定された時間に等しくしようとします。timer オブジェクトがタイマー関数コールバックの実行間 Period プロパティに指定された時間より長く待機しなければならない場合、時間調整のために続く実行の期間を短縮します。

参考

関連するトピック