No, you don't need sync/atomic. The mutex is sufficient. By the way, you
should put the mutex inside of guardedState, next to the data being
guarded. Had you done that originally, Go Vet would have complained about
you passing guardedState by value (mutexes should never by copied).

https://play.golang.org/p/yuYjhSzdBoQ


On Sun, Apr 14, 2019 at 9:51 AM <michael.f.el...@gmail.com> wrote:

> Thanks, Skip. That fixes it. Is the need for a pointer receiver documented
> somewhere? It's not something that even crossed my mind given that the
> neither the compiler nor golint complained.  I suppose it makes sense if I
> think of func (x) foo(y) {} as being an alternate way of writing func
> foo(x, y) {}. In that case, it's clear that a copy of x is being passed
> since that's Go's default.
>
> While this topic is still alive, I'd like to ask a follow-on question: Is
> the use of sync/atomic actually needed in this example or is it sufficient
> to wrap all accesses in mutex Lock/Unlock (using the same mutex, of course).
>
>
>
> On Sunday, April 14, 2019 at 12:08:55 PM UTC-4, Skip wrote:
>>
>> The receiver for load and update should be the original object not a copy.
>>
>> https://play.golang.org/p/XCZC0OVhGMa
>>
>> On Sun, Apr 14, 2019, 7:56 AM <michae...@gmail.com> wrote:
>>
>>>
>>> https://play.golang.org/p/6aQYNjojyBD
>>>
>>> I'm clearly missing something about the way sync.Mutex and atomic.Value
>>> work in Go.
>>>
>>> I'm attempting to write a pair of concurrency safe methods, load() and
>>> update(), for accessing a struct.  The struct is stored as an atomic.Value
>>> and accessed with atomic.Load and atomic.Value.  I'm also wrapping the
>>> accesses within a mutex Lock/Unlock.  That's probably unneeded for my
>>> load() method but I added it trying to figure out why it's not returning
>>> updated info. In my minimal example below (also in the Go Playground link
>>> above) the output of main() should be:
>>>
>>> s={65535}
>>> v={65535}
>>>
>>> but I get
>>>
>>> s={65535}
>>> v={0}
>>>
>>> indicating that the updated value is not available after the call to
>>> update().
>>>
>>> The only thing I'm doing that's a little different from the examples in
>>> the doc for sync/atomic is passing a function that takes a pointer to a
>>> struct instance to my update function. I do that to make it easy to write
>>> code that updates just a few items in the state struct (which in my real
>>> application has many members instead of just one as shown here.)
>>>
>>> Apologies for wasting the group's time if I've overlooked a brain-dead
>>> error, but I've been fooling with this for several hours now and can't see
>>> why it shouldn't be working,
>>>
>>>
>>> package main
>>>
>>> import (
>>> "fmt"
>>> "sync"
>>> "sync/atomic"
>>> )
>>>
>>> type state struct {
>>> R4000 uint16
>>> }
>>> type guardedState struct {
>>> v atomic.Value
>>> }
>>>
>>> var stateMutex = sync.Mutex{}
>>> var gState guardedState
>>>
>>> func init() {
>>> gState.v.Store(state{})
>>> }
>>>
>>> func (g guardedState) load() state {
>>> stateMutex.Lock()
>>> defer stateMutex.Unlock()
>>> s := gState.v.Load()
>>> return s.(state)
>>> }
>>>
>>> func (g guardedState) update(f func(*state)) {
>>> stateMutex.Lock()
>>> defer stateMutex.Unlock()
>>> s := g.v.Load().(state)
>>> f(&s)
>>> g.v.Store(s)
>>> }
>>>
>>> func main() {
>>> f := func(s *state) {
>>> s.R4000 = 65535
>>> fmt.Printf("s=%v\n", *s)
>>> }
>>> gState.update(f)
>>> v := gState.load()
>>> fmt.Printf("v=%v\n", v)
>>> }
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golan...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to