実行時における関数のスレッドのコントロール

スレッドは、コンピュータで動作しているプログラムの連続した実行と同種のものです。スレッドはコンピュータのオペレーティングシステムによって管理されます。システムは、絶えずスレッドの休止、再開を行なうことによって、シングルプロセッサ上で、多くの動作が同時に実行される効果を作り出しています。例えば、1つのスレッドで e-mail を読んでいる間に、他のスレッドでインターネットから楽曲をダウンロードすることができます。オーバードライブ(Overdrive)オプションがオンにされると、Max は2つのスレッドを使い、オペレーティングシステムに対して1つのスレッドを確保するよう要請します。これを高い優先度のスレッドと呼び、可能な限り定期的に(通常全てのミリセカンドで)動作します。これと引き換えに、Max はこのスレッド内で生じた処理によって使用されるコンピュータの時間を可能な限り少なくすることを保証しようとします。時間のかかる処理やユーザーインタラクション(ユーザとの対話による)処理は、低い優先度のスレッドに割り当てられます。

2つのスレッドによって、Max を使って、高い時間精度を必要とする処理(MIDIなど)を、コンピュータに負荷のかかる処理(ビデオの復元など)や、ユーザによる入力が必要な処理と同時に行わせることが可能になります。

ところで、js はこのマルチスレッドシナリオにどのように適合するのでしょうか?デフォルトでは、js オブジェクトは全ての Javascript コードを低い優先度のスレッドで実行します。特に、それ自身が高い優先度のスレッドで実行されていることに気づくと、低い優先度で実行されることになっている処理の実行を延期させます。しかし、関数の immediate プロパティを設定することによって、js に対してこれを行なわないように命じることができます。

例えば、次のように、誰かがあなたの js オブジェクトを metro に接続した時に動作することを意図した bang 関数を作ったとします。

bang 関数は、アウトレットから数値を送るというような、単純な動作を行ないます。

var value = 1; function bang() { outlet(0,value); }

この関数が、不特定の遅いタイミングで実行される低い優先度のスレッドに置かれて遅延されるのではなく、bang を受け取った時に直ちに実行されれば時間の精度は向上します。そのためには、次の文をグローバルコードの中に書いておきます。

bang.immediate = 1;

しかし、関数の immediate プロパティがセットされたからといって、常にこれが高い優先度で実行されるというわけではありません。優先度は js オブジェクトが関数の実行の要請を受け取ったときのコンテキストによって決まります。例えば、上の例の js オブジェクトに接続された bang ボタンをクリックした場合、マウスクリックが常に低い優先度で扱われるため、 bang 関数は低い優先度のスレッドで実行されます。

次の例はやや微妙です。例えば、immediate プロパティがセットされていない関数 slowbang を書いたとします。これは、単に 上で書いた bang 関数を呼出すだけのものです。

function slowbang() { bang(); }

次のように、metroslowbang メッセージに接続されている新しいパッチを作ったと仮定します。

この場合、bang が実行される前に、slowbang が低い優先度のスレッドに回されてしまうため、bang 関数はもはや高い優先度のスレッドでは実行されません。

Javascript コードが実行されている現在のスレッドは、max オブジェクトの mainthread プロパティをテストすることによって判断できます。コードが低い優先度のスレッドで実行されている場合、mainthread プロパティは 1 になります。

まとめると、関数が高い優先度のスレッドで実行されるのは...

  • 関数の immediate プロパティがセットされている場合。

    かつ

  • js が関数を高い優先度で呼び出すためのメッセージを受け取る場合。

    または

  • 関数が Task オブジェクトを介して実行される場合。

となります。

高い優先度のスレッドで許容されるもの

immediate プロパティは、一般的に、Max パッチのロジックに関与するコンピュータの短い動作を実行するような関数を対象としています。言い換えると、js オブジェクトが、連続したコンピュータ処理の中間にある、実行順序やタイミング精度を保つことが重要であるような場所に位置する場合に、そこで使用します。immediate プロパティを、描画やパッチャーのスクリプティングのような処理の終端にあたる動作で使うことは適切ではありません(実際、使用できません)。

高い優先度のスレッドは次のような動作で使うことができます。

  • outlet 関数を使ってメッセージを送信する場合。

  • post を使って Max ウィンドウにメッセージを表示させる場合。(メッセージが表示される順序の保証はありません)

  • あなたが定義した他の Javascript 関数を呼び出す場合。

  • Task オブジェクトにアクセスしたり、それをコントロールする場合。

  • 数値演算、文字列処理、論理演算を実行する場合。

  • jsthis や max オブジェクトの標準のプロパティにアクセスする場合。

次のような処理は、高い優先度のスレッドで実行させようとした場合、動作の保証はありません。ほとんどの場合、これを行なうことに対する保護は存在せず、Max のクラッシュを含む予期しない動作を招いてしまう可能性があります。(しかし、このようなケースが見つかった場合、私たちはそれを阻むような最前の策を講じたいと思っています)

  • jsui の機能を使う場合。Sketch、Image オブジェクトの生成や、これらのオブジェクトのメソッドの呼び出しのようなものが、これにあたります。

  • File または Folder クラスを使ったファイルやフォルダへのアクセス。

  • Patcher、Maxobj、Wind オブジェクト、およびそのメソッドの中で、スクリプティングやアプリケーションコントロール機能を使用する場合。