Is string assignment "atomic"?

2,694 views
Skip to first unread message

Miki Tebeka

unread,
Sep 3, 2012, 5:59:46 PM9/3/12
to golan...@googlegroups.com
Greetings,

This is just my curiosity.

Assume I have a string assignment, is there a scenario where a different go routine reads the value of the assigned string and get a "partial" string?
For example:
    str := "hello"
    other := "there"
    // some time later
   str = other

Is it possible that during "str = other", some other goroutine who reads the value of str will get something which is not either "hello" or "there"?

From looking a bit in the assembly output, I *think* you can only get either "hello" or "there" since it's a new pointer assignment.
But I'd like to check if I got it right.

Thanks,
--
Miki

Dan Kortschak

unread,
Sep 3, 2012, 6:10:30 PM9/3/12
to Miki Tebeka, golan...@googlegroups.com
Try it...

package main

import (
"fmt"
)

func main() {
var (
k string
i = "hello"
j = "there"
)

done := false
go func() {
for !done {
k = i
k = j
}
}()
for {
if p := k; p != "" && p != i && p != j {
fmt.Println(p)
done = true
break
}
}

return

Jan Mercl

unread,
Sep 3, 2012, 6:11:59 PM9/3/12
to Miki Tebeka, golan...@googlegroups.com

It isn't.

-j

Evan Shaw

unread,
Sep 3, 2012, 6:11:52 PM9/3/12
to Miki Tebeka, golan...@googlegroups.com
String assignment is not specified to be atomic and it is not atomic
in practice either. No assignments of any type are specified to be
atomic, in fact.

If an assignment is not somehow synchronized (via sync.Mutex, channel,
or some other way), there is no guarantee that another goroutine will
see the full update or if it will ever see the update at all.

In practice, this means a goroutine can observe a string with the
wrong length. In your example this doesn't matter since "hello" and
"there" have the same length, but if the strings were "hi" and "there,
a mismatched string length would give you a very unexpected result.

- Evan

Jesse McNelis

unread,
Sep 3, 2012, 6:13:01 PM9/3/12
to Miki Tebeka, golan...@googlegroups.com
On Tue, Sep 4, 2012 at 7:59 AM, Miki Tebeka <miki....@gmail.com> wrote:
> Assume I have a string assignment, is there a scenario where a different go
> routine reads the value of the assigned string and get a "partial" string?
> For example:
> str := "hello"
> other := "there"
> // some time later
> str = other
>
> Is it possible that during "str = other", some other goroutine who reads the
> value of str will get something which is not either "hello" or "there"?

http://golang.org/ref/mem
The memory model doesn't guarantee that any assignment is atomic.



--
=====================
http://jessta.id.au

Peter S

unread,
Sep 3, 2012, 8:36:12 PM9/3/12
to Jesse McNelis, Miki Tebeka, golan...@googlegroups.com

Actually there is a paragraph that I think could be interpreted as a guarantee that string assignment is atomic; see the last example in "Channel communication" http://golang.org/ref/mem#tmp_69 :

If the channel were buffered (e.g., c = make(chan int, 1)) then the program would not be guaranteed to print "hello, world". (It might print the empty string; it cannot print "goodbye, universe", nor can it crash.)

Peter

 


--
=====================
http://jessta.id.au

David Symonds

unread,
Sep 3, 2012, 8:43:27 PM9/3/12
to Peter S, Jesse McNelis, Miki Tebeka, golan...@googlegroups.com
On Tue, Sep 4, 2012 at 10:36 AM, Peter S <spete...@gmail.com> wrote:

> Actually there is a paragraph that I think could be interpreted as a
> guarantee that string assignment is atomic; see the last example in "Channel
> communication" http://golang.org/ref/mem#tmp_69 :
>
> If the channel were buffered (e.g., c = make(chan int, 1)) then the program
> would not be guaranteed to print "hello, world". (It might print the empty
> string; it cannot print "goodbye, universe", nor can it crash.)

Yeah, that doc seems wrong on that point.

Larry Clapp

unread,
Sep 3, 2012, 8:52:27 PM9/3/12
to golan...@googlegroups.com, Jesse McNelis, Miki Tebeka
I don't read it that way.  As near as I can tell, in the example given the two threads were synchronized via a channel.  It doesn't address the atomicity of string assignment either way.

-- Larry

David Symonds

unread,
Sep 3, 2012, 8:57:47 PM9/3/12
to Larry Clapp, golan...@googlegroups.com, Jesse McNelis, Miki Tebeka
On Tue, Sep 4, 2012 at 10:52 AM, Larry Clapp <la...@theclapp.org> wrote:

> I don't read it that way. As near as I can tell, in the example given the
> two threads were synchronized via a channel. It doesn't address the
> atomicity of string assignment either way.

The final paragraph is the one in question, and it supposes a buffered
channel. In that case there is no synchronisation between the sender
and receiver, only a happens-before relationship, and so the printing
of 'a' and the assignment of 'a' are still racing.


Dave.

Larry Clapp

unread,
Sep 3, 2012, 9:06:38 PM9/3/12
to golan...@googlegroups.com, Larry Clapp, Jesse McNelis, Miki Tebeka
Ah, I get it now, thanks.

-- L
 

Peter S

unread,
Sep 3, 2012, 11:39:03 PM9/3/12
to David Symonds, Jesse McNelis, Miki Tebeka, golan...@googlegroups.com
I filed issue 4039 for this.

I am wondering if there is any specific reason ref/mem doesn't explicitly state anything about atomicity guarantees or lack thereof; doing so could possibly reduce confusion regarding concurrency.

Peter

Miki Tebeka

unread,
Sep 4, 2012, 3:03:19 PM9/4/12
to golan...@googlegroups.com
Thank you all for the fast and educational replies, this list rock!
Reply all
Reply to author
Forward
0 new messages