提供: Japanese Scratch-Wiki

2020年9月8日 (火) 17:54時点におけるApple502j (トーク | 投稿記録)による版 (Sequencer.stepThreadの動作)

このきじは ひらがなのページがありません。ごめんなさい。編集者向け:作成する

スレッド(英: thread)は、Scratchのプログラムを実行する際の最小単位で、多くの場合1スクリプトが1スレッドに対応する。シーケンサー(英: sequencer)は、スレッドの動作を制御する。

Scratchのプログラムは、実際には同時実行しない。以下の順位で実行される:

スレッド

スレッドは、各スクリプトを表現している。ただし、定義ブロックは、呼び出し元のスレッドによる実行となり、定義ブロック用のスレッドによって行われるわけではない。スレッドには以下の状態がある:

定数 説明
STATUS_RUNNING 0 スレッドは実行中。
STATUS_PROMISE_WAIT 1 スレッドは非同期で実行されていて、実行完了を待っている。
STATUS_YIELD 2 スレッドの次の実行まで待つ。
STATUS_YIELD_TICK 3 次のフレームまで待つ。
STATUS_DONE 1 スレッドは実行を終了した。

フレーム

Scratchは、1秒間に30回描画する。(フレーム)そして、シーケンサーは、以下の条件をすべて満たす限り、1フレーム内で可能な限り多くのスレッドを実行する:

  • 実行時間は、1フレームの75%未満(25ミリ秒程度)
  • STATUS_DONEではないスレッドが存在する。
  • フレーム内の2回目以降の実行では、STATUS_RUNNINGであるスレッドが存在する。
  • ターボモードであるか、またはステージの再描画が要求されていない。

1フレーム内の動作順序は次の通り:

  • 強制的に終了させられたスレッドを当該フレームの実行対象から外す。
  • 条件駆動のハットブロックを実行させる。
  • ステージモニターの値の更新を予約する。
  • タイマーを更新する。
  • スレッドの実行。(ステージモニターの値の計算を含む)
  • 実行が終了したスレッドを次のフレームの実行対象から外す。
  • スクリプトのハイライトを更新する。
  • 緑の旗のハイライトを更新する。
  • ステージを描画する。
  • スプライト情報を更新する。
  • ステージモニターを更新する。

スタックとスタックフレーム

スレッドは、スタックの集まりである。1つのスタックは、1つのスタックブロックや、それに接続できるブロック(C型ブロックやハットブロック、キャップブロックなど)を表している。それぞれのスタックには、「スタックフレーム」というものがあり、そのスタックに関する情報を保管する。たとえば、() 回繰り返すブロックは、残りの繰り返し回数をスタックフレームに保管している。

スタックは、前のブロックの実行後に動的に追加される。このため、前のブロックの実行中にブロックを後ろにつなげても、つなげたブロックが実行される。C型ブロックの場合は、条件を満たした場合は中にあるブロックを次のスタックとして追加する。

スレッドの実行

スレッドの実行は以下の通りに行われる:

  • スレッドにスタックがもうない場合は、実行を終了して次のスレッドに移る。
  • スレッドがSTATUS_YIELD_TICKであり、かつこのフレームでスレッドがまだ実行されていない場合は、スレッドの状態をSTATUS_RUNNINGにする。(つまり、STATUS_YIELD_TICKはフレームの最初でのみ実行される。)
  • STATUS_RUNNINGまたはSTATUS_YIELDのスレッドに対しては:
    • スタックを取得する。もしそれがnullの場合(例: 空のCブロック)は、次のスタックに進み、それでもスタックがない場合(ハットブロック単独の場合など)はスレッドを止める。
    • ブロックを可能な限り実行する:
      • 「再描画せずに実行」モードの場合は、500ミリ秒のタイマーを設定する。この場合、ブロックが500ミリ秒以内に実行し終わった時は、STATUS_YIELDの場合も実行を続ける。
      • スレッドの実行元のスプライトが削除された場合は、実行を終了する。
      • それ以外の場合は、そのスタックを実行する。
      • スレッドがSTATUS_YIELDの場合は、他のスレッドに処理を移す。(ただし、「再描画せずに実行」モードで前述のタイマーが時間切れでない場合を除く。)
      • スレッドがSTATUS_PROMISE_WAITの場合は、非同期実行されたブロックが実行し終わるまでなにもできないので、他のスレッドに処理を移す。
      • スレッドがSTATUS_YIELD_TICKの場合は、次の処理はフレームの最初まで待たないといけないので、他のスレッドに処理を移す。
      • 実行中のスタックが変化していない場合(C型ブロックの分岐にはまっていない場合)は、次のブロックに進む。
      • 次のスタックがない場合(C型ブロックの内部の終わりなど)は、スタックが見つかるまで以下を繰り返す:
        • スタックを取得する。
        • スタックがもうない場合は、STATUS_DONEにして終了する。
        • 取得したスタックがループするC型ブロックの場合は、他のスレッドに処理を移す。(ただし、「再描画せずに実行」モードで前述のタイマーが時間切れでない場合を除く。)ループのブロックが次に実行されたときに、条件を再チェックしどのブロックに進むか決める。
        • 次のブロックに進む。
Cookieは私達のサービスを提供するのに役立ちます。このサービスを使用することにより、お客様はCookieの使用に同意するものとします。