Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Verifying my mental model about goroutines and access to closure variables
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  10 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Manuel Kiessling  
View profile  
 More options Aug 16 2012, 5:06 am
From: Manuel Kiessling <man...@kiessling.net>
Date: Thu, 16 Aug 2012 02:06:24 -0700 (PDT)
Local: Thurs, Aug 16 2012 5:06 am
Subject: Verifying my mental model about goroutines and access to closure variables

Hello all,

I'm currently writing my first "serious" http server application with Go. I
would like to make sure that I correctly grasp some of the conceptual
implications related with it.

My server is, as far as I can see, basically your standard
http.ListenAndServe thing, nothing special.

One of my handlers generates an id whenever there is a POST request to
/sessions, like so:

var id int

func generateId() {
  id = id + 1
  return id

}

func CreateSession(res http.ResponseWriter, req *http.Request) {
  io.WriteString(res, strconv.Itoa(generateId()))

}

Now, first I made a mental note along the lines of *"guess I need to manage
the id generation through a channel in order to avoid a mess when
concurrent http requests (== goroutines) access the id closure"*. But my
tests showed that no such problem occured, the session id is incremented
correctly no matter how many concurrent http requests I fire at POST
/sessions (using ab).

Now my mental model is that id = id + 1 seems to be atomic - there is no
copy of id's value "somewhere" at any time, it is incremented in place. To
verify this, I rewrote the code to:

var id int

func generateId() {
  curr := id
  time.Sleep(1000 * time.Millisecond)
  id = curr + 1
  return id

}

which, as expected, led to problems, that is, concurrent http requests
resulting in concurrent goroutines all accessing "id", incrementing it by 1
from an "old" value that is no longer true.

Is that more or less a correct mental model?

Regards,
Manuel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jim Whitehead II  
View profile  
 More options Aug 16 2012, 5:18 am
From: Jim Whitehead II <jnwhi...@gmail.com>
Date: Thu, 16 Aug 2012 10:18:30 +0100
Local: Thurs, Aug 16 2012 5:18 am
Subject: Re: [go-nuts] Verifying my mental model about goroutines and access to closure variables

The memory model makes very minimal guarantees, and
http://golang.org/ref/mem will help you better understand those. The
moral of the story is you shouldn't rely on the assignment being
atomic.

A fairly standard way of dealing with this is to turn generateId into
a goroutine that sits in a simple loop that manages the counter:

http://play.golang.org/p/MAQnFBBgKA

Just one way you might think about it. The memory model won't
guarantee that an assignment is atomic in all cases, so its simpler to
ensure the correct synchronization (and leads to a nice design).

- Jim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jan Mercl  
View profile  
 More options Aug 16 2012, 5:20 am
From: Jan Mercl <0xj...@gmail.com>
Date: Thu, 16 Aug 2012 11:20:39 +0200
Local: Thurs, Aug 16 2012 5:20 am
Subject: Re: [go-nuts] Verifying my mental model about goroutines and access to closure variables

On Thu, Aug 16, 2012 at 11:06 AM, Manuel Kiessling <man...@kiessling.net>wrote:

> Is that more or less a correct mental model?

I think you've observed correctly what happens in the Go implementation
you're using, where properly aligned, small enough variables (int qualifies
AFAIK), may be and usually are updated atomically on any modern
HW. However, the Go's memory model doesn't guarantee this to be reliably
usable. The compiler is free to "hide" the updates (wrt other goroutines)
to any variable as long as there's no synchronization performed, e.g. the
updated value may actually exist in a register only, thus not visible after
a context switch.

In short, such code will work, but doesn't have to work in general (think
any other Go implementation). That's other way how to say that the code is
invalid.

-j


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
minux  
View profile  
 More options Aug 16 2012, 5:21 am
From: minux <minux...@gmail.com>
Date: Thu, 16 Aug 2012 17:21:17 +0800
Local: Thurs, Aug 16 2012 5:21 am
Subject: Re: [go-nuts] Verifying my mental model about goroutines and access to closure variables

On Thu, Aug 16, 2012 at 5:06 PM, Manuel Kiessling <man...@kiessling.net>wrote:

it's not atomic in the current gc amd64 implementation, and you can't
assume that either
(please refer to Go Memory Model <http://golang.org/ref/mem> docs for
details)

if you just want to maintain a counter, you can use
sync/atomic.AddInt32<http://golang.org/pkg/sync/atomic/#AddInt32> or
a channel of ids (preferable).


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Manuel Kiessling  
View profile  
 More options Aug 16 2012, 5:37 am
From: Manuel Kiessling <man...@kiessling.net>
Date: Thu, 16 Aug 2012 02:37:15 -0700 (PDT)
Local: Thurs, Aug 16 2012 5:37 am
Subject: Re: [go-nuts] Verifying my mental model about goroutines and access to closure variables

Great, that was exactly the kind of implementation I was thinking of -
until (wrongly) realizing that it doesn't seem to be necessary.

Thanks,
Manuel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter  
View profile   Translate to Translated (View Original)
 More options Aug 16 2012, 11:54 am
From: Peter <peter.armit...@gmail.com>
Date: Thu, 16 Aug 2012 08:54:32 -0700 (PDT)
Local: Thurs, Aug 16 2012 11:54 am
Subject: Re: Verifying my mental model about goroutines and access to closure variables

Are you calling runtime.GOMAXPROCS(n) with n >1? Not doing this could
result in the behaviour you witness, as your server would only allow 1
goroutine at a time to access id, making it look atomic.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Manuel Kiessling  
View profile  
 More options Aug 16 2012, 12:18 pm
From: Manuel Kiessling <man...@kiessling.net>
Date: Thu, 16 Aug 2012 18:18:05 +0200
Local: Thurs, Aug 16 2012 12:18 pm
Subject: Re: [go-nuts] Re: Verifying my mental model about goroutines and access to closure variables

Good point, I'll verify that.

Regards,
--
  Manuel

Am 16.08.2012 um 17:54 schrieb Peter <peter.armit...@gmail.com>:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
 
View profile   Translate to Translated (View Original)
 More options Aug 16 2012, 12:56 pm
From: ⚛ <0xe2.0x9a.0...@gmail.com>
Date: Thu, 16 Aug 2012 09:56:24 -0700 (PDT)
Local: Thurs, Aug 16 2012 12:56 pm
Subject: Re: Verifying my mental model about goroutines and access to closure variables

On Thursday, August 16, 2012 11:06:24 AM UTC+2, Manuel Kiessling wrote:

> Now my mental model is that id = id + 1 seems to be atomic - there is no
> copy of id's value "somewhere" at any time, it is incremented in place.

The operation can be conceptually split into these steps:

1. Read id into a goroutine-private variable V
2. Increment V by 1
3. Write V to id

If goroutine1 is executing these steps, goroutine2 which is also executing
these steps can interrupt goroutine1 between step 1 and 2, or between step
2 and 3.

Each goroutine executing these steps has its own V.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Will Madison  
View profile  
 More options Aug 17 2012, 2:24 pm
From: Will Madison <wmadison...@gmail.com>
Date: Fri, 17 Aug 2012 11:24:33 -0700 (PDT)
Local: Fri, Aug 17 2012 2:24 pm
Subject: Re: [go-nuts] Verifying my mental model about goroutines and access to closure variables

This is very very minor butl here's a small bug fix to +Jim Whitehead 's
excellent example: http://play.golang.org/p/8bDLK-iWtp

(Simple oversight in that the inner goroutine never wrote to the "done"
channel to inform the caller of its status)

- Will


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Shuai Lin  
View profile  
 More options Aug 18 2012, 2:27 am
From: Shuai Lin <linshuai2...@gmail.com>
Date: Fri, 17 Aug 2012 23:27:36 -0700 (PDT)
Local: Sat, Aug 18 2012 2:27 am
Subject: Re: Verifying my mental model about goroutines and access to closure variables

My 2 cents:

Another key point is that the current scheduler is not *preemptive*.  With
the current sheduler implementation, a goroutine would not be switched out
by the scheduler until it encounters some blocking call, e.g, lock a mutex,
or a blocking syscall.

If the scheduler is preemptive, there may still be race conditions with the
op's code even with GOMAXPROC = 1.

Lin.

在 2012年8月16日星期四UTC+8下午11时54分32秒,Peter写道:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »