マルチスレッド

マルチスレッドが有効になっていると、任意の数のシーケンスが並列で実行されるようなモデルを表現した図を作成することができるようになります。この機能は、設定ダイアログや、編集メニューの中でON/OFFを切り替えることができます。オプションによっては、それぞれのスレッドが関連するライフラインはそれぞれ違う色で描かれ、識別しやすいようになっています。本当の意味での並列化というものは存在していなく、メッセージは特定の順序で実行されます。この順序は、多くのスレッドのスイッチで、とりうる方法のひとつであると解釈できます。シングルプロセッサのシステムでは、似たような方法でこれらを実行します。

マルチスレッドを使った図の仕様作成

マルチスレッドの図を作成するのは、シングルスレッドの図を作成するのにくらべて、多少難しい程度です。

スレッドの生成

新しくスレッドを生成すると、古いスレッドとは、関連するライフラインの色が異なるため、区別することができます。数多くのスレッドを生成したい場合には、色が途中からリピートされます。スレッドは0から始まる、連続する数値を属性にもっています。

静的なスレッドの生成

"t"フラグセットをが宣言時にしていされたオブジェクトはスレッドになります。例えば:

o:Object[t]

このスクリプトは、静的に生成されたスレッドを持つようになります。このスレッドに関して、最初に行われるのは、関連するオブジェクトからのメッセージを受信になるでしょう。

"t"フラグセットがついたオブジェクトが一切なかった場合にも、シングルスレッドがひとつだけ準備されます。このオブジェクトは、他のオブジェクトから最初のメッセージを受け取ると、起動開始になります。

動的なスレッドの生成

ルール上は、アクターからオブジェクトに対して送られるメッセージに対しては、新しいスレッドが生成されることになっています。

そのため、メッセージは”アクティブオブジェクト”に対して送信されます。オブジェクトをアクティブであると宣言するには、以下のように"v"フラグを使用することができます:

worker:BackgroundWorker[v]

メッセージを送信し、通常のオブジェクトが受信したときに新しいスレッドを生成する、ということもあるでしょう。このようなスレッドを生成するメッセージを指定するには、呼び出し元とメッセージの間の区切り文字のコロン(:)の前に">"を追加します:

object:>bar.foo()

このスクリプトの意味は、objectオブジェクトが新しいスレッドを作成することをあらわします。そして、そのスレッドが生成されて最初に、barオブジェクトのfooメソッドの実行するという意味になります。

ノート

このようなスレッド生成メッセージを使うと、返り値を定義することができません。もしも新しいスレッド上で動作しているオブジェクトと、生成を行ったオブジェクトの間でコミュニケーションさせたい場合には、明示的なメッセージ送信を使用してください。

メッセージのブロードキャスト

セット表記を利用すると、ひとつ以上の呼び出し先オブジェクトにメッセージを送ることができます。この場合、これをブロードキャストメッセージと呼びます:

caller:{callee1,callee2,callee3}.broadcast

呼び出し先は、このセットの中に重複して登場してはいけません。また、呼び出し元もセットの中に入れてはいけません。このブロードキャストメッセージを利用すると、それぞれの呼び出し先ごとにスレッドが生成されます。

現在のバージョンでは、ブロードキャストメッセージによってアクティブ化されるオブジェクトに対して、ニーモニックを定義することはできません。

活動開始時のスレッドの指定

ひとつ以上のスレッドを使用している場合に、どのスレッド上でメッセージを送っているのか、というのが指定できなければなりません。そのため、角括弧で指定する、呼び出し元オブジェクトのレベル指定の後ろに、スレッドの番号を設定することができます。レベルと、スレッドの番号は、以下のサンプルのようにカンマ(,)で区切ります:

object[0,3]:bar.foo()

このスクリプトの意味は、このobjectオブジェクトがfoo()メッセージを三番目のスレッドを使用してbarオブジェクトに送っている、となります。

もしもオブジェクトがシングルスレッドからしか使用されない場合には、スレッドの番号は省略することができます。もしもオブジェクトを操作するスレッドがひとつ以上あり、スレッド番号が省略されている場合には、エディタは、メッセージの送信に使われるスレッドは、一番最後にメッセージを送ったのと同じスレッドであるとみなします。新しいスレッドが生成された場合に、他のスレッドが指定されなければ、新しいスレッドを通じて送信されたものとみなします。上記のようなスレッドの番号を特定してメッセージを送りたい場合には、レベルを省略してobject[,3]:bar.foo()と書くこともできます。この場合、ゼロというのがデフォルトのレベルを示すので、この書き方と上記の書き方は同じ意味を表します。

角括弧の中には数値以外にも、ニーモニックを私用することができます。オブジェクトに対してニーモニックを定義すると、レベル、スレッド番号の両方の決定に使用します。

オプションの”Threads”の項目にある”Show thread numbers”にチェックを入れると、スレッド番号が見えるようになります。アクティブなライフラインの最上段に表示されるようになります。

その場でのリターン

通常、スレッドの実行ポイントは、スレッドが停止されたり、別のメッセージが送信されない限りは、最新のメッセージを受信したオブジェクト上にいます。しかし、スレッドの実行ポイントが長期間とあるオブジェクトの上に滞留し続けるのが適当ではない場合もあるでしょう。その場合には"&"を付加すると、即座にメッセージに対する返答が返ってくるということを表現することができます。ただし、その場でのリターンのメッセージを受け取ったオブジェクトは、後で送信するメッセージで送信者として指定することはできません:

foo:bar.notify()&

もしも、スレッド生成メッセージの後ろに"&"が付くと、生成されたスレッドはなにもしないで、その場で破棄されます。このようなメッセージは非同期のシグナルとして使用されます。

スレッドの停止

通常のケースでは、スレッドは図の最後まで生き残りますが、場合によっては、それ以外の場所でスレッドが停止されるようなモデルを作成する必要があることもあるでしょう。この場合には、以下の形式の擬似メッセージをスクリプトの中に挿入します:

object:stop

スレッドの番号を指定することもできます。もし、スレッドの活動が他のオブジェクトから戻ってくる前には、オブジェクトが破棄できる前に、スレッドを停止する必要があるかもしれません。擬似メッセージのテキスト("stop")は図の中には表示されません。目に見える効果としては、スレッドが終了するタイミングでライフラインが終了するというものがあります。

制御フローを返す

オブジェクトがメッセージを送る前にスレッドの制御フローを返すということは、スレッドが返すべき返事が保留されているということを意味します。場合によっては、新しいメッセージを送らないで、とある種類の実行が終了したということや、なんらかの”クリーンアップ”を実行した、ということを表現したいというケースがあるでしょう。この場合には、1文字のアンダースコア(_)で構成される擬似メッセージを使用します:

object:_

これを指定すると、”オブジェクト”がメッセージを送信できるようになるまで、返事を待つことができるようになります。これについても、スレッド番号を指定することができます。擬似メッセージは図の中には表示されません。答えを返すのに必要なスペースを除いて、余計なスペースが含まれなくなります。