Hi, the second one is better.

The lock should only protect the shared data. In this case, gMap.

In the first case, you are protecting some computations which are not accessing 
any shared data.

On November 7, 2016, at 4:03 AM, 刘桂祥 <liuguixiang...@gmail.com> wrote:


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