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.