2017-12-16 33 views
2

最終的には、最初の次元が使用されたジャンプルーチンの数と等しい2次元スライスになり、2番目の次元はそれぞれのgo-routineが書き込みを担当する構造体のリスト。各スレッドが最初の次元で独自のインデックスを取得する2次元スライスのスレッドセーフ

タイプ:

[][]*Node 

各ゴールーチンは、2Dスライス内の最初の次元のインデックスを与えられますし、それだけのインデックスでリストに追加します。

私の最初の本能はこれが大丈夫だと思っていましたが、同時に2つのゴールーチンをそれぞれのリストに追加する必要がある場合、これは同時に第1次元スライスに書き込んでいることを意味します。

私が代わりにこの同時書き込みを軽減するかもしれない、生のリストを使用しての第2のリストへのポインタを考えていた...何かのように:

workCollector := make([]*[]*Node, 5) 
for i ; i < 5; i++ { 
    go.Process(i) 
} 

func Process(threadNum int){ 
    localList := workCollector[threadNum] 
    *localList = append(*localList, NewNode(UUID.())) 
} 

は各ゴールーチンは、自分のリストに追加できるようにするには、この十分ですミューテックスに追加が必要なのでしょうか?

答えて

1

あなたのゴルーチンの数が一定であり、各ゴルーチンが「独自の」データだけを変更している場合、独自のアプローチはスレッドセーフです。

私の最初の本能は、これは大丈夫だと思っていましたが、同時に2つのゴールーチンをそれぞれのリストに追加する必要がある場合は、同時に第1次元スライスに書き込んでいます。

あなたは同時にそのスライスに書き込んでいるかもしれませんが、バッキングアレイの異なるインデックスを更新していて、そのスライスを成長させる必要がない場合、バッキングアレイは移動しません。

+0

あなたの答えをありがとう。スライスへの書き込みがスレッドセーフであると保証されない理由は、スライスサイズが変更される可能性があるからです。スライス内の2つのインデックスは、スライスのサイズ変更を引き起こさない限り、異なるスレッドによって同時に更新することができます。そうですか? –

関連する問題