should I use ?? mu.Lock() temp := make(map[int]int) temp[1] = 100 temp[2] = 200 gMap = temp mu.Unlock()
or temp := make(map[int]int) temp[1] = 100 temp[2] = 200 mu.Lock() gMap = temp mu.Unlock() 在 2016年11月4日星期五 UTC+8下午9:59:45,Ian Lance Taylor写道: > > On Thu, Nov 3, 2016 at 11:30 PM, 刘桂祥 <liuguix...@gmail.com <javascript:>> > wrote: > > > > very thanks , I am unfamiliar with the cpu out-of-order execution , > but > > I doubt if my three line code is related ,it will reorder it ?? > > I want to be clear that the real problem is not out-of-order > execution, it is memory ordering. On modern multi-core processors > there is no guarantee that one core will see memory writes in the > order they are done by a different core. Making that guarantee > requires an explicit memory barrier instruction, and there is no such > instruction in your example program. > > Ian > > > > 在 2016年11月4日星期五 UTC+8下午1:38:12,Ian Lance Taylor写道: > >> > >> On Thu, Nov 3, 2016 at 10:28 PM, 刘桂祥 <liuguix...@gmail.com> wrote: > >> > > >> > In my write goroutine I don't modify the map key (data structure) > but > >> > set > >> > the variable point to another map address ,this is a pointer > assignment > >> > and > >> > is atomic > >> > >> You're right, my previous reply was incorrect. My apologies. The > >> real reason your code is incorrect is more subtle. > >> > >> A map is a pointer to a complex data structure. Setting values in a > >> map is a series of memory writes. From the point of view of the > >> processor doing the writes, they all appear in order. From the > >> pointer of view of a different processor, they need not. It is > >> possible the the other processor to see the final write, to gMap, > >> before it sees the other writes, setting the values in the map. The > >> read from gMap will then be trying to access an incomplete data > >> structure. > >> > >> In order to force all the writes to be visible to the reading > >> processor, you need to use a sync.Mutex, a channel operation, or a > >> sync/atomic.Store function. > >> > >> There is a simple rule to follow when it comes to communicating > >> between processes: always use channels or locks. Don't try to be > >> clever. Please read > >> > >> > https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong. > > > >> > >> Ian > >> > >> > 在 2016年11月4日星期五 UTC+8下午1:22:20,Ian Lance Taylor写道: > >> >> > >> >> On Thu, Nov 3, 2016 at 10:19 PM, 刘桂祥 <liuguix...@gmail.com> wrote: > >> >> > can you explain why whis ? > >> >> > >> >> A map is basically a pointer to a complex data structure. Setting a > >> >> value in a map changes that data structure. If one goroutine is > >> >> reading from the data structure while a different goroutine is > writing > >> >> to the data structure, the results are completely unpredictable. In > >> >> the worst case they could even cause the program to crash. > >> >> > >> >> Ian > >> >> > >> >> > >> >> > 在 2016年11月4日星期五 UTC+8下午1:16:39,Ian Lance Taylor写道: > >> >> >> > >> >> >> On Thu, Nov 3, 2016 at 8:37 PM, 刘桂祥 <liuguix...@gmail.com> > wrote: > >> >> >> > // example.go > >> >> >> > > >> >> >> > package main > >> >> >> > > >> >> >> > var gMap = make(map[int]int) > >> >> >> > > >> >> >> > func w() { > >> >> >> > temp := make(map[int]int) > >> >> >> > temp[1] = 100 > >> >> >> > temp[2] = 200 > >> >> >> > gMap = temp // Does the compiler or cpu will reorder > >> >> >> > temp[1]=100, > >> >> >> > temp[2]=200, gMap=temp ?? > >> >> >> > } > >> >> >> > > >> >> >> > func r() { > >> >> >> > local := gMap > >> >> >> > println(local[1], local[2]) > >> >> >> > } > >> >> >> > > >> >> >> > func main() { > >> >> >> > > >> >> >> > go w() > >> >> >> > go r() > >> >> >> > > >> >> >> > // ... > >> >> >> > } > >> >> >> > > >> >> >> > I have one goroutine to read the map and one goroutine to > rewrite > >> >> >> > the > >> >> >> > global > >> >> >> > map variable does this safe ?? > >> >> >> > >> >> >> No. Use a lock. > >> >> >> > >> >> >> Ian > >> >> > > >> >> > -- > >> >> > 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...@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...@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...@googlegroups.com <javascript:>. > > 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.