Thank you for the explanation and the code sample

But the case here is indeed as Marvin explained, There is race condition. 
But in my example, I make sure that wg done is to protect result pointer 
before calling it to caller. 

with this structure some one could easily introduce a race condition if he 
tried to access the result pointer.

What I would like to understand if there is case that my snippet causes 
race condition.

This is my understanding.
1. Heap memory is shared between go rountine in the same process
2. main routine create a pointer to some struct on the heap (initially nil)
3. the go routine allocate memory on the heap for the `foo` struct
4. the go routine assign main's result pointer
5. wg.Done() ensure that step 4 is done before it released
6. process will always returns value generated by the go routine.

And I would like to make sure that my understanding of heap is correct. 
That is shared per process and there are no heap copying between go routine.

Thanks for the response so far, It is really interesting discussion for me 
:)

On Monday, August 22, 2016 at 3:47:03 PM UTC+2, Joubin Houshyar wrote:
>
>
>
> On Saturday, August 20, 2016 at 2:29:41 AM UTC-4, Yulrizka wrote:
>>
>> Dear gophers
>>
>> I have discussion with my colleague about this code
>>
>>
>> func process() *foo {
>>     var result *foo
>>
>>     var wg sync.WaitGroup
>>     wg.Add(1)
>>     go func() {
>>         defer wg.Done()
>>         result = &foo{1}
>>     }()
>>
>>     wg.Wait()
>>
>>     return result
>> }
>>
>> He argues that this is heap race condition. 
>> the result variable which lives on the heap of the go routine is not 
>> guaranteed to be synced to the result on the process func's thread.
>> The better approach would be using a channel instead. I may agree with 
>> him that probably using channel is better.
>> But I would like to understand the reasoning behind that.
>>
>> I thought that `wg.Wait()` guaranteed that the process func's thread wait 
>> until go func is finsihed and sync everything so that the result variable 
>> is safe to return.
>>
>> Probably I'm missing some knowledge about how go routine work.
>>
>> 1. Does the process func thread has separate heap than the go func? If so 
>> how does is sync?
>> 2. From I read so far, when go routine needed a bigger stack, it 
>> allocates memory from the heap. So what happened for object that is 
>> allocated inside of the go routine once the go routine returns?
>>
>> I there article of source that go into details about this I would love to 
>> read it :)
>>
>> Warm regards,
>>
>
> Your firend is correct that using a WaitGroup here does not in anyway 
> address concurrent access to the heap variable 'result'. 
>
> This modified example should clear it up:
>
> package main
>
> import (
>     "fmt"
>     "sync"
> )
>
> func main() {
>     var i int
>     for {
>         r := process()
>         if r.v == 8 {
>             fmt.Printf("%d\n", i)
>             panic("eight!")
>         }
>         i++
>     }
> }
>
> type foo struct {
>     v int
> }
>
> func process() *foo {
>     var result *foo
>     var wg sync.WaitGroup
>
>     wg.Add(1)
>     go func() {
>         defer wg.Done()
>         result = &foo{1}
>     }()
>
>     // race condition on result
>     result = &foo{8}
>
>     wg.Wait()
>     return result
> }
>
> The issue here is the runtime scheduler and what execution order can occur 
> before the go routine execution 'process' has been stopped at wg.Wait. So 
> process can return a foo initiazed with either 1 or 8. 
>
> I think the general Go developer intuiton here is that the go routine will 
> not run until the parent go routine has hit the wg.Wait (since there are no 
> explicit IO or blocking instructions between the go func() and wg.Wait. 
> However, using Go(1.7) the main loop will panic after as little as 1000 
> loops.
>
>

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