19

ここにいくつかの背景があります:
リーキーバケットのようなものに使用される、goルーチン間で共有されるカウンター変数が必要です。効果的な実行の同時セクションにリーキーバケットの例があることは知っていますが、追跡する必要のある数が非常に多い可能性があり、チャネル内の要素の数を使用して追跡するのは非効率的だと感じています。そのため、異なるルーチン間で共有変数を使用して数を追跡することを検討しています。

明示的な構成がないと、すべてのgoルーチンが1つのスレッドにマップされることを理解しています。しかし、マルチコアコンピューターのプログラムに複数のスレッドを割り当てる場合、インクリメント演算子はアトミックですか?異なるマシン(、、)上の異なるデータ型(、、など)でもint32すべて同じですか?float32x86_32x86_64arm

より具体的にはcounter += 1000、あるルーチンとcounter -= 512別のルーチンにあり、2つのルーチンがたまたま2つのスレッドで実行されている場合はどうなりますか?スレッドの安全性について心配する必要がありますか?鍵をかけましょうcounterか?

4

1 に答える 1

25

いいえ、増分はアトミックであると想定してはなりません。アトミック加算関数またはミューテックスを使用します。

仮定しましょう:

import "sync/atomic"
var counter = new(int32)

あるゴルーチンはミューテックスなしで実行できましたがatomic.AddInt32(counter, 1000)、別のゴルーチンは実行できatomic.AddInt32(counter, -512)ました。

ミューテックスを使用したい場合:

import "sync"
var counter int32
var mutex sync.Mutex

func Add(x int32) {
    mutex.Lock()
    defer mutex.Unlock()
    counter += x
}
于 2012-12-17T05:06:15.933 に答える