2017-01-08 4 views
3

GOARCH=amd64オプションを指定してビルドし、64ビットOSで実行している場合、golangのポインタ値のサイズは32ビットか64ビットですか?は、golangのポインタ値atomicの読み取りまたは書き込み操作ですか?

64ビットサイズの場合、そのポインタ値の読み取りまたは書き込み操作がアトミックに実行されるように、グローバルポインタ値がメモリ内で8バイトに揃えられていますか?

たとえば、次のコードでは、読み込みゴルーチンがポインタを読み取ったときにグローバルポインタpが部分的に更新される可能性はありますか?

var p *int 

void main() { 
    i := 1 
    p = &i 
    go func() { 
     fmt.Println(*p) 
    }() 
} 

私が関係していますシナリオは一つだけの書き込みがあることはあるが、複数のグローバルポインタ値を読み出し、そのポインタの古い値の読み取りが重要ではありません。前もって感謝します!

+0

いいえ、唯一のアトミック操作は 'sync/atomic'です。常に読み書きを同期させる必要があります。 – JimB

+0

[参照](http://stackoverflow.com/q/41406501/720999)。 – kostix

答えて

3

原子レベルで動作することが保証されているのは、sync.atomicの操作だけです。

ロックを取る必要があるかどうかを確認するには、例えばsync.Mutexを使用するか、原子プリミティブのいずれかを使用します。ポインタを使用するあらゆる場所でそれらを使用しなければならないため、素粒子のプリミティブを使用することはお勧めできません。ミューテックスを使用して

はOK行くスタイルです - あなたは非常に簡単にロックすると、現在のポインタを返すように関数を定義することができ、例えば

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() 
} 
のようなもの

これらの機能がどの意志顧客へのポインタのコピーを返しますマスターポインタが変更されても一定に保たれます。これは、あなたの要件がどのように時間的に重要であるかに応じて、受け入れ可能である場合もあります。未定義の動作を避けるだけで十分です。ガベージコレクタは、指されたメモリがプログラムによって使用されなくなっても、ポインタが常に有効であることを保証します。

代わりのアプローチは、1つのgoルーチンからのポインタアクセスのみを行い、チャネルを使用してルーチンを実行するように指示することです。それはもっと慣れ親しんだものと見なされますが、あなたのアプリケーションに正確に適合しないかもしれません。

Here is an example atomic.SetPointerの使い方を示しています。安全ではないため、むしろ醜いです。ただし、安全でない。ポインタのキャストは何もコンパイルされないため、ランタイムコストは小さい。

import (
    "fmt" 
    "sync/atomic" 
    "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)) 

} 
+0

私はunsafe.Pointerを使うのはむしろ醜いことに同意します。また、具体的な型へのポインタを定義する代わりに、unsafe.Pointer型の変数を定義する必要があります。 'var p *構造体=&構造体{}'。 – ncubrian

関連する問題