5.7 スレッドの同期

# スレッドの同期

一度、関数やスレッドを使用したとても高度なライブコーディングを行うと、おそらくスレッド内にある間違いを直すことが、とても簡単なことを理解できるでしょう。あなたはコードを起動してスレッドを再スタートさせることが容易にできるので、それは全然大したことではないのでしょう。しかし、スレッドを再スタートさせるときは、元々のスレッドとは調子がずれる事になります。

## 継続時間

以前話した時に、新しいスレッドが`in_thread`として作られると元のスレッドのすべてのセッティングが継続されることを学びました。これは現在の時間を含んでいます。つまり、スレッドが同時にスタートするときには常に他のスレッドと同期していることを意味しています。

しかし、１つのスレッドを起動したときは、それは独自の時間で再生されるので、他の現在実行中のスレッドと同期していることはほとんどありません。

## Cue と Sync

Sonic Pi は`cue`と`sync`という関数を使ってこの問題の解決方法を提供します。
`cue`はすべての他のスレッドに向けてビートメッセージを送ることができます。初期状態の他のスレッドでは、これらのビートのメッセージは関係付けられず、無視されます。しかし、`sync`関数を使えば、あなたは簡単にこの関連付けを登録することができるのです。

`sync`という機能は、一定の時間、実行中のスレッドを止める`sleep`という関数と非常に似ていることに気づくことが重要です。しかし、`sleep`ではどのくらい休止させるかを決めることができましたが、`sync`ではそれを決めることができず、`sync`は長さに関わらず、次の`cue` が出てくるまで待つのです。

それでは、もうちょっと詳しくみていきましょう。

```
in_thread do
 loop do
   cue :tick
   sleep 1
 end
end

in_thread do
 loop do
   sync :tick
   sample :drum_heavy_kick
 end
end
```

ここではふたつのスレッドが使われています。ひとつは音はなりませんがメトロノームのような機能として `:tick` を使って一秒ごとにビートの情報を送っています。2つ目のスレッドはは`tick`の情報と同期し、そのビートの情報を受け取った際に、 `cue` のスレッドの時間に情報を引き継ぎ、起動を続けます。

この結果、`:drum_heavy_kick`のサンプル音源は、厳密に同時のスタートでないふたつのスレッドであったとしても、他のスレッドに `:tick` からの情報をきっちり受け取って正確にビートを刻んだ音が聞けるはずです。

```
in_thread do
 loop do
   cue :tick
   sleep 1
 end
end

sleep(0.3)

in_thread do
 loop do
   sync :tick
   sample :drum_heavy_kick
 end
end
```

このちょっとやっかいな `sleep(0.3)`は一つ目のスレッドとはあまり関係のない2つ目のスレッドを作り出してしまいます。しかしながら、`cue`や`sync`を使えば、タイミングがずれてしまうようなアクシデントを回避してくれます。

## Cueの名前

`cue`には`:tick`以外のどんな好きな名前でも付けられます。その際には他のスレッドと動機させるために必ず正しい名前を使用する必要があります。もし違った場合、永遠に（もしくはストップボタンを押すまで）それは`cue`の情報を待ち続けることになります。

それでは`cue`の名前付けを見てみましょう。

```
in_thread do
 loop do
   cue [:foo, :bar, :baz].choose
   sleep 0.5
 end
end

in_thread do
 loop do
   sync :foo
   sample :elec_beep
 end
end

in_thread do
 loop do
   sync :bar
   sample :elec_flip
 end
end

in_thread do
 loop do
   sync :baz
   sample :elec_blup
 end
end
```

ここではメインの`cue`でビートメッセージをランダムに`:foo`と`:bar`、`:baz`に送るよう設定しています。それから3つのスレッドがそれぞれ独自に同期して、それぞれ設定されたサンプルの音を再生します。この関係付けられた結果から、`cue`のスレッドによって、それぞれが同期しながら0.5秒刻みに`syncスレッドの音がランダムに再生され、そしてサンプルが再生されます。

逆に`sync`スレッドを次の`cue`まで居座り続けさせ待たせるように、
それらのスレッドに送るように設定しても、もちろんそれは動作します。

