ホームページ >バックエンド開発 >Golang >Go におけるポインタの割り当てはアトミックであり、どうすれば安全にできるのでしょうか?

Go におけるポインタの割り当てはアトミックであり、どうすれば安全にできるのでしょうか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-24 14:09:10301ブラウズ

Is Pointer Assignment Atomic in Go, and How Can It Be Made Safe?

Go でアトミックにポインターを割り当てる

Go には同時実行性を管理するためのさまざまなツールが用意されていますが、よく生じる疑問の 1 つは、ポインターを割り当てるかどうかです。はアトミック操作です。

のアトミック操作Go

Go では、アトミックであることが保証されている操作は、sync.atomic パッケージにある操作のみです。そのため、ポインタの割り当てはネイティブにアトミックではありません。

安全なポインタ割り当て

ポインタをアトミックに割り当てるには、2 つのオプションがあります:

  1. ロックの取得: ロックの使用 (例: sync.Mutex) により、一度に 1 つの goroutine だけがポインターにアクセスできるようになり、競合状態が防止されます。
  2. アトミック プリミティブの使用: sync.atomic パッケージは、atomic.StorePointer や atomic.StorePointer などのアトミック プリミティブを提供します。 atomic.LoadPointer、ポインターのアトミックな割り当てと取得に使用できます。 value.

Mutex を使用した例

ポインターの割り当てを保護するために sync.Mutex を使用する例を次に示します。

import "sync"

var secretPointer *int
var pointerLock sync.Mutex

func CurrentPointer() *int {
    pointerLock.Lock()
    defer pointerLock.Unlock()
    return secretPointer
}

func SetPointer(p *int) {
    pointerLock.Lock()
    secretPointer = p
    pointerLock.Unlock()
}

Atomic を使用した例プリミティブ

または、アトミック プリミティブを使用してアトミック性を実現できます。

import "sync/atomic"
import "unsafe"

type Struct struct {
    p unsafe.Pointer // some pointer
}

func main() {
    data := 1

    info := Struct{p: unsafe.Pointer(&data)}

    fmt.Printf("info is %d\n", *(*int)(info.p))

    otherData := 2

    atomic.StorePointer(&info.p, unsafe.Pointer(&otherData))

    fmt.Printf("info is %d\n", *(*int)(info.p))
}

考慮事項

  • sync.atomic の使用にキャストする必要があるため、コードが複雑になる可能性がありますunsafe.Pointer.
  • ロックは一般的に Go では慣用的であると考えられていますが、アトミック プリミティブの使用は推奨されていません。
  • 別のアプローチは、ポインター アクセスに単一の goroutine を使用し、チャネル経由でコマンドを通信することです。 Go の同時実行モデルとよりよく連携します。

以上がGo におけるポインタの割り当てはアトミックであり、どうすれば安全にできるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。