Go で変数のスレッドセーフを実装する方法
Java では、同期変数の概念により、単一のスレッドのみが実行できることが保証されますいつでも特定のコードブロック。ただし、Go は明示的な同期キーワードを提供しません。
根拠
Go は、「共有によって通信しない」という原則に基づいて、スレッド同期に対する異なるアプローチを推進しています。代わりに、コミュニケーションによって記憶を共有します。」これは、共有メモリへの直接アクセスを避け、チャネルなどの通信ベースのメカニズムを選択することを意味します。
ミューテックスベースの同期
ミューテックスが必要なシナリオに遭遇した場合、これを実装する方法は次のとおりです。 Go:
var ( mu sync.Mutex protectMe int ) func getMe() int { mu.Lock() me := protectMe mu.Unlock() return me } func setMe(me int) { mu.Lock() protectMe = me mu.Unlock() }
改善点
アトミック同期
単一の値を保護する必要がある場合は、sync/atomic の使用を検討してください。パッケージ:
var protectMe int32 func getMe() int32 { return atomic.LoadInt32(&protectMe) } func setMe(me int32) { atomic.StoreInt32(&protectMe, me) }
通信ベースアプローチ
Go は、ゴルーチン間の通信にチャネルの使用を推奨し、共有変数の必要性を排除します。たとえば、パブリッシャー/サブスクライバー パターンの場合:
type topic struct { subscribing []chan int } var t = &topic{} func subscribe() chan int { ch := make(chan int) t.subscribing = append(t.subscribing, ch) return ch } func publish(v int) { for _, ch := range t.subscribing { ch <- v } }
このアプローチにより、メモリを共有せずにスレッドセーフな通信が保証されます。
以上がGo でスレッド セーフを実現する方法: ミューテックス、アトミックス、またはチャネル?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。