3

複数のゴルーチンから保護されていないグローバル変数にアクセスすると競合状態が発生する可能性がある、Golang の典型的なデータ競合の 1 つを理解しようとしています。

var service map[string]net.Addr

func RegisterService(name string, addr net.Addr) {
  service[name] = addr
}

func LookupService(name string) net.Addr {
  return service[name]
}

ミューテックスで保護することでこれを解決できると言われています。

var (
  service   map[string]net.Addr
  serviceMu sync.Mutex
)

func RegisterService(name string, addr net.Addr) {
  serviceMu.Lock()
  defer serviceMu.Unlock()
  service[name] = addr
}

func LookupService(name string) net.Addr {
  serviceMu.Lock()
  defer serviceMu.Unlock()
  return service[name]
}

ここまでは順調ですね。私を混乱させているのはこれです:

この質問に対する受け入れられた回答は、CPU バウンドのゴルーチンが、同じ OS スレッドに多重化された他のゴルーチンを枯渇させることを示唆しています (明示的に で譲らない限りruntime.Gosched())。これは理にかなっています。

私には、上記のRegisterService()およびLookupService()関数は CPU バウンドのように見えます。IO も利回りもないからです。これは正しいです?

そうであり、GOMAXPROCS が 1に設定されている場合、上記の例のミューテックスは依然として厳密に必要ですか? 競合状態が発生する可能性がある時点で、ゴルーチンが CPU バウンドであるという事実は、それを処理しませんか?

たとえそうなったとしても、GOMAXPROCS が何に設定されているかを保証できないかもしれないので、実際にはミューテックスを使用することはまだ良い考えだと思います。他に理由はありますか?

4

1 に答える 1