2016-10-17 1 views
2

私はネット/ httpサーバーを作成しています。私のリクエストハンドラは、別のジャンプルーチンによって更新される共有データにアクセスする必要があります。このルーチンは単一の構造体を更新したままにし、すべてのnet/httpハンドラは同じ構造体にアクセスする必要があります。Go:データの同期化と共有方法

type MyData struct { 
    Expiration time.Time 
    A string 
    B string 
    C string 
} 

func update(data MyData) { 
    go func() { 
    for { 
     if data.Expiration >= time.Now() { 
     // set A, B, C 
     } 
     // sleep 
    } 
    }() 
} 

共通のMyDataを他のゴールーチンで使用できるようにするにはどうすればよいですか?私はチャンネルを考えていましたが、チャンネルのすべての読者は同じMyDataを取得する必要があります。問題は、チャンネルからの読み込みがアイテムをチャンネルからポップすることです。私は、読者側でPeek()、更新する時にライター側でDrain()を探す方法を探していると思います。

+2

あなたは、単一のリソースの周りの「相互排除」をしたいときは、通常、[「ミューテックス」](https://golang.org/pkg/sync/#Mutexを)したいです – JimB

+1

自明ではありません。頻繁に更新される場合は、MutexまたはRWLockが必要です(複数の同時読み取りが可能な場合)。それが更新されているよりもはるかに頻繁に読み込まれている場合(毎回使用されている設定+まれに更新されているconfigのような)、atomic.Valueのポインタを持ち、リフレッシュするときに新しいインスタンスに置き換えることができます。 – twotwotwo

+0

@twotwotwo:ありがとう。それが私が考えたものです。私は私の構造体のMY_DATAグローバル変数を作るとしましょう。構造体にRWLockを安全に置くことができますか、またはmutexを別のグローバル変数にする必要がありますか? – fandingo

答えて

3

ミューテックスベースのソリューション

type MyData struct { 
    Expiration time.Time 
    A string 
    B string 
    C string 
} 

type MutexedMyData struct { 
    sync.RWMutex 
    MyData MyData 
} 

var m = &MutexedMyData{} 


func (m *MutexedMyData) Update(my_data MyData) { 
    m.Lock() 
    m.MyData = my_data 
    m.Unlock() 
} 

func (m *MutexedMyData) Read() MyData { 
    u.RLock() 
    value := m.MyData 
    u.RUnlock() 

    return value 
} 
+0

ありがとう!クイック初心者質問:func宣言の '(m * MutexedMyData) 'の意味は何ですか? – fandingo

+1

[struct on methods](http://golangtutorials.blogspot.ru/2011/06/methods-on-structs.html)では、m.Updateまたはm.Readとして使用できます –

関連する問題