Think Stitch
PRINCIPIA  最近の更新


インターリーブによる多対1通信

インターリーブを使うと、1つのチャネルで複数のプロセスからの通信を受けることができます。 つまり、多対一の通信を実現することができます。

インターリーブによる多対一通信の例

送信プロセス

まず複数の送信プロセスを用意します。 各プロセスには番号 k で ID を振ります。 ここでは単純にプロセス ID を送信して終了することにします。

(define-process (P k)
  (! ch (k) SKIP))

受信プロセス

受信側は1つのチャネル ch で受信を待つだけです。 ここではカウンタ n を用意して、送信プロセスと同じ数だけ受信したら終了するようにしました。

(define-process (Q n)
  (if (= n 0)
      SKIP
      (? ch (x) (Q (- n 1)))))

システムプロセス

プロセスを並行合成してシステムプロセスを作ります。 まず送信プロセスをインターリーブで合成します。 次にチャネルを同期リストに指定して、受信プロセスと合成します。

(define-process SYS
  (par (list ch)
    (Q N)
    (xpar k (interval 0 N) '()
      (P k))))

シミュレーション

計算木は次のようになります。 受信が行われる順序は非決定的になります。

プロセス ID による送信者の識別

上の例ではデータとしてプロセス ID を渡しました。 一般にはデータだけからは送信者を識別することはできません。 そこでデータとは別に、チャネルの引数にプロセス ID を加えれば、送信者を識別することができます。 チャネルの定義を次のようにします。

(define-channel ch (pid data) ...)

このようにすると送信者を識別できるだけでなく、プロセス ID でガードすれば、特定のプロセスからの送信だけを受け取ることができます。

プロセス ID の付いたチャネルをインターリーブで共有することは、原理的には各送信者のために個別のチャネルを用意するのと同じです。 どちらを使うかは(モデルの範囲では)趣味の問題だと思います。 これらに対して、プロセス ID のないインターリーブは抽象化されたモデルということになります。

2013/08/24
© 2013,2014,2015 PRINCIPIA Limited