ゴルーチンは識別子を意図的に持たない
スレッドはだいたいIDがもらえるもの。その実体はポインタだが、それを使えばスレッドローカル領域が簡単に作れる。こんな感じで: local[Thread.id] = { data: 'foo' }。スレッド間のデータのやり取りにも使われたりする。スレッドローカル領域はたいてい悪用されがちである。 プログラミング言語Goに書いてあるのはこんな例。
現在処理しているHTTPリクエストに関する情報を得るために、多くの関数でスレッドローカル領域を調べることが普通となっています。
どう困るか、とかも書いてある。
しかし、グローバル変数に過剰に依存しているプログラムと全く同様に、そのような状況は不健全な「少し離れた処理」、つまり、関数の振る舞いが引数だけで決まるのではなく、関数を実行しているスレッドの識別子で決まるということになってしまいます。結果として、スレッドの識別子が変更される、たとえば何らかのワーカースレッドが手伝うといったことで、その関数は不可解な誤った振る舞いをします。
関数の挙動が引数だけに依存せず、コンテキストに依存するのが危険ということを言っている。しかもそういう挙動にしてしまうということで、他のワーカーに手伝わせるということがやりにくくなってしまうと。そのとおりですね。
Railsとかはそのへん、結構怖いかな…。昔コード書いてた頃、こんなこと気にせず書いていたわ mactkg.icon
goroutineで値を渡す方法は色々あるけど、基本はチャネルを介すか、引数として渡すかしかないので、明確ではあるかな。ポインタ渡しちゃったらまあ確かにアレかもしれないですけど。しかしスレッドの識別子が変わって見てるものが全く別物ってことにはなりにくい。