FAQ
I'm not English speeking, so excuse me :)
When I wish to implement a singleton var in two ways below:

1. There's a package called "singleton", and there's a public var called
"S" inside it. That's the function testRightSingleton()
2. There's a local var called "s", and inside the second function. That's
the function testWrongSingleton()

Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
And I found that the first testRightSingleton() function is slower than the
second, and as I tried many times I occasionally found second function call
initializes the value many times, but I didn't see this happpened in the
first one.

Code like this:

main.go:

func testRightSingleton() {
// global value auto thread safe?
c := make(chan bool)
f := func() {
if singleton.S == nil {
singleton.S = "value"
log.Println("init value")
}
c <- true
}
const COUNT = 1000000
for i := 0; i < COUNT; i++ {
go f()
}
for i := 0; i < COUNT; i++ {
<-c
}
// result may like this:
// 2014/01/16 23:06:00 init value
}
func testWrongSingleton() {
c := make(chan bool)
var s interface{} = nil
f := func() {
if s == nil {
s = "value"
log.Println("init value")
}
c <- true
}
const COUNT = 1000000
for i := 0; i < COUNT; i++ {
go f()
}
for i := 0; i < COUNT; i++ {
<-c
}
// result may like this:
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
// 2014/01/16 23:07:00 init value
}
func testSingleton() {
runtime.GOMAXPROCS(runtime.NumCPU())
testRightSingleton()
testWrongSingleton()
}

singleton.go:

// start
package singleton
var S interface{} = nil
// end

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Jan Mercl at Jan 16, 2014 at 5:06 pm
    On Thu, Jan 16, 2014 at 4:23 PM, wrote:

    No "home" (variable, field of a struct variable, function
    parameter/result, receiver, stuff pointed to by pointers, TLD
    whatever...) is safe for concurrent access unless the access is
    coordinated by locks (http://golang.org/pkg/sync/) or
    synchronization: http://golang.org/ref/mem or the access is performed
    atomically (http://golang.org/pkg/sync/atomic/).

    -j

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Donovan Hide at Jan 16, 2014 at 5:36 pm
    If you can enforce a read only map you can fill it in init() and it's safe
    for concurrent access:

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


    On 16 January 2014 17:06, Jan Mercl wrote:

    On Thu, Jan 16, 2014 at 4:23 PM, wrote:

    No "home" (variable, field of a struct variable, function
    parameter/result, receiver, stuff pointed to by pointers, TLD
    whatever...) is safe for concurrent access unless the access is
    coordinated by locks (http://golang.org/pkg/sync/) or
    synchronization: http://golang.org/ref/mem or the access is performed
    atomically (http://golang.org/pkg/sync/atomic/).

    -j

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Donovan Hide at Jan 16, 2014 at 5:48 pm
    P.S. don't export package level maps - protect them with a read-only Get
    method:

    http://play.golang.org/p/0WoM2ZyMLm

    If you need an updatable map, have a look at some lock examples here:

    https://github.com/kisielk/sqlstruct/blob/master/sqlstruct.go
    http://golang.org/src/pkg/encoding/json/encode.go (encoderCache)



    On 16 January 2014 17:36, Donovan Hide wrote:

    If you can enforce a read only map you can fill it in init() and it's safe
    for concurrent access:

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


    On 16 January 2014 17:06, Jan Mercl wrote:

    On Thu, Jan 16, 2014 at 4:23 PM, wrote:

    No "home" (variable, field of a struct variable, function
    parameter/result, receiver, stuff pointed to by pointers, TLD
    whatever...) is safe for concurrent access unless the access is
    coordinated by locks (http://golang.org/pkg/sync/) or
    synchronization: http://golang.org/ref/mem or the access is performed
    atomically (http://golang.org/pkg/sync/atomic/).

    -j

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Robert Johnstone at Jan 16, 2014 at 6:14 pm
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is in
    an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you to
    write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var called
    "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function. That's
    the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Haohua li at Jan 17, 2014 at 2:57 am
    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine
    is a little slow?

    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is in
    an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you to
    write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var called
    "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function. That's
    the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at Jan 17, 2014 at 4:17 am

    On Fri, Jan 17, 2014 at 1:57 PM, haohua li wrote:

    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine
    is a little slow?
    Can you please write a benchmark to demonstrate this.

    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is
    in an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you
    to write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var called
    "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function.
    That's the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Haohua li at Jan 17, 2014 at 5:27 am
    I wrote a benchmark to compare accessing speed between package var and
    local var by closure. I found accessing of package var is much slower than
    local var when "runtime.GOMAXPROCS(runtime.NumCPU())" is set.
    On the other hand, accessing outer local var by closure is a little bit
    slower when GOMAXPROCS is not set (remaining 1 cpu core). I think there's a
    little job need to be done when accessing variable reference by closure.
    Here's the benchmark code. Thanks!

    main.go:
    http://play.golang.org/p/EYeqMIuP7A<https://mail.xiaomi.com/owa/redir.aspx?C=rMsKy6JgXkKw2HBHLYxhMeznSzu85NAIruG0OZWI1Rj7HlHe9KSnuR6TT5kXPtz2fIt0GVoYtuM.&URL=http%3a%2f%2fplay.golang.org%2fp%2fEYeqMIuP7A>

    singleton.go:
    package singleton
    var S interface{} = "origin value"

    在 2014年1月17日星期五UTC+8下午12时17分14秒,Dave Cheney写道:



    On Fri, Jan 17, 2014 at 1:57 PM, haohua li <lihao...@gmail.com<javascript:>
    wrote:
    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine
    is a little slow?
    Can you please write a benchmark to demonstrate this.

    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is
    in an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you
    to write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var
    called "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function.
    That's the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Haohua li at Jan 17, 2014 at 5:30 am
    Multi-core results are like this:
    time: 275.446435ms
    time: 70.649482ms

    Single-core like this:
    time: 220.208856ms
    time: 241.159269ms

    在 2014年1月17日星期五UTC+8下午12时17分14秒,Dave Cheney写道:



    On Fri, Jan 17, 2014 at 1:57 PM, haohua li <lihao...@gmail.com<javascript:>
    wrote:
    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine
    is a little slow?
    Can you please write a benchmark to demonstrate this.

    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is
    in an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you
    to write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var
    called "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function.
    That's the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Haohua li at Jan 17, 2014 at 5:45 am
    I wrote a benchmark to compare accessing speed between package var and
    local var by closure. I found accessing of package var is much slower than
    local var when "runtime.GOMAXPROCS(runtime.NumCPU())" is set.
    On the other hand, accessing outer local var by closure is a little bit
    slower when GOMAXPROCS is not set (remaining 1 cpu core). I think there's a
    little job need to be done when accessing variable reference by closure.
    Here's the benchmark code. Thanks!

    main.go:
    http://play.golang.org/p/EYeqMIuP7A

    singleton.go:
    package singleton
    var S interface{} = "origin value"



    Multi-core results are like this:
    time: 275.446435ms
    time: 70.649482ms

    Single-core like this:
    time: 220.208856ms
    time: 241.159269ms


    在 2014年1月17日星期五UTC+8下午12时17分14秒,Dave Cheney写道:



    On Fri, Jan 17, 2014 at 1:57 PM, haohua li <lihao...@gmail.com<javascript:>
    wrote:
    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine
    is a little slow?
    Can you please write a benchmark to demonstrate this.

    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is
    in an init function for the package. The initialization should be thread
    safe, and the compiler will ensure that it gets called once and in the
    right order.

    Alternatively, you may be interested in sync.Once. This will allow you
    to write a function like testRightSingleton correctly.
    http://play.golang.org/p/SEJxEEDnxt

    Robert

    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:

    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var
    called "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function.
    That's the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than
    the second, and as I tried many times I occasionally found second
    function call initializes the value many times, but I didn't see this
    happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end
    --
    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/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • 李皓骅 at Jan 17, 2014 at 1:31 pm
    A wrote a benchmark to compare accessing speed between package var and local var by closure. I found accessing of package var is much slower than local var when "runtime.GOMAXPROCS(runtime.NumCPU())" is set.
    On the other hand, accessing outer local var by closure is a little bit slower when GOMAXPROCS is not set (remaining 1 cpu core). I think there's a little job need to be done when accesing variable refrence by closure.
    Here's the benchmark code. Thanks!
    main.go:
    http://play.golang.org/p/EYeqMIuP7A

    singleton.go:
    package singleton
    var S interface{} = "origin value"

    ________________________________
    发件人: Dave Cheney [dave@cheney.net]
    发送时间: 2014年1月17日 12:17
    收件人: haohua li
    抄送: golang-nuts; 墙角的小猫; 李皓骅
    主题: Re: [go-nuts] Re: Is package public var thread safe?




    On Fri, Jan 17, 2014 at 1:57 PM, haohua li wrote:
    Hi, thanks all of your significant replies.
    There's a small question: why is package exported var access by goroutine is a little slow?

    Can you please write a benchmark to demonstrate this.


    在 2014年1月17日星期五UTC+8上午2时14分14秒,Robert Johnstone写道:
    Hello,

    As mentioned by Donovan, the natural place to initialize a singleton is in an init function for the package. The initialization should be thread safe, and the compiler will ensure that it gets called once and in the right order.

    Alternatively, you may be interested in sync.Once. This will allow you to write a function like testRightSingleton correctly. http://play.golang.org/p/SEJxEEDnxt

    Robert


    On Thursday, 16 January 2014 10:23:10 UTC-5, haohua li wrote:
    I'm not English speeking, so excuse me :)
    When I wish to implement a singleton var in two ways below:

    1. There's a package called "singleton", and there's a public var called "S" inside it. That's the function testRightSingleton()
    2. There's a local var called "s", and inside the second function. That's the function testWrongSingleton()

    Finally set GOMAXPROCS as CPU number and testSingleton() tests them.
    And I found that the first testRightSingleton() function is slower than the second, and as I tried many times I occasionally found second function call initializes the value many times, but I didn't see this happpened in the first one.

    Code like this:

    main.go:

    func testRightSingleton() {
    // global value auto thread safe?
    c := make(chan bool)
    f := func() {
    if singleton.S == nil {
    singleton.S = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:06:00 init value
    }
    func testWrongSingleton() {
    c := make(chan bool)
    var s interface{} = nil
    f := func() {
    if s == nil {
    s = "value"
    log.Println("init value")
    }
    c <- true
    }
    const COUNT = 1000000
    for i := 0; i < COUNT; i++ {
    go f()
    }
    for i := 0; i < COUNT; i++ {
    <-c
    }
    // result may like this:
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    // 2014/01/16 23:07:00 init value
    }
    func testSingleton() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    testRightSingleton()
    testWrongSingleton()
    }

    singleton.go:

    // start
    package singleton
    var S interface{} = nil
    // end

    --
    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+unsubscribe@googlegroups.com .
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 16, '14 at 4:34p
activeJan 17, '14 at 1:31p
posts11
users6
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase