You might be interested in this:
https://golang.org/pkg/sync/atomic/#Value


Le lundi 12 septembre 2016 17:04:39 UTC+2, sqweek E. a écrit :
>
> Ok so after getting away with using maps to share data between threads for 
> a loooong time, I've finally seen the light and accepted that this is not 
> safe.
>
> In my case the threads in question are a painter thread and a 
> mouse/keyboard event processing thread. They want to share data because 
> obviously a mouse hitbox needs to match what is being drawn on the screen, 
> unless you're going for a ux that drives your users insane :)
>
> Anyway as I said it's not safe to concurrently read and write a map; 
> eventually this will result in a panic. Yet I'm stuck with a codebase that 
> does this all over the place. So despite hating the thought of blocking 
> either thread I did what any honest java-for-dayjob coder would do and 
> resigned myself to hiding the maps behind an RWLock.
>
> Of course things are never that simple; adding locks to code that was not 
> designed with them in mind is a good way to introduce deadlocks 
> (particularly of the 
> recursive-read-lock-while-other-thread-is-acquiring-write-lock variety). I 
> made another change to address recursive lock acquisition, realised I 
> missed a couple of shared maps and suddenly locking code was strewn all 
> over my program; I got to the point of acquiring a read-lock every time the 
> mouse moved before giving up in disgust. I thought about using an actual 
> concurrent map, but giving up the builtin map's ease of use and 
> well-typedness didn't thrill me. After some thought I came up with an 
> alternative approach...
>
> TLDR; My shared structures are *mostly* read-only, in the sense that read 
> operations are much more common than writes. I decided I can afford to 
> change the writes so instead of updating the maps in place, they (a) take a 
> copy of the current map (b) update the copy and (c) replace the reference 
> to the original map (held in a struct field) with the updated copy.
>
> I was pretty chuffed with this approach. It's clearly not the most 
> efficient but it allowed me to solve the panic without risking deadlock. 
> I'd be surprised if I'm the first person to come up with it, but I haven't 
> seen it mentioned - the majority of advice seems to be "use an RWLock" or 
> "use a concurrent map".
>
> I'm interested in understanding how safe/portable the approach is. I'm no 
> expert on ARM/memory barriers but my understanding is that without an 
> explicit sync/channel operation there's no guarantee another thread will 
> see a change (in this case, the new map instance). In my case I have a 
> channel based notification mechanism running alongside to wake up the 
> painter thread when something changes, I'm just not sure what memory 
> changes that is guaranteed to communicate.
>
> I also just wanted to share the approach and see how other people feel 
> about it. It reminds me a bit of a double-buffering - writing to the 
> backbuffer and then swapping it into action.
>
> -sqweek
>

-- 
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