FAQ
rand.Intn panic in goroutine, below is stack info

panic: runtime error: index out of range

goroutine 7 [running]:
math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
/usr/local/go/src/math/rand/rng.go:244 +0xc1
math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
/usr/local/go/src/math/rand/rand.go:46 +0x39
math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
/usr/local/go/src/math/rand/rand.go:52 +0x21
math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
/usr/local/go/src/math/rand/rand.go:87 +0xc1
math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
/usr/local/go/src/math/rand/rand.go:101 +0x92

code is

package main

import (
//"io"
"fmt"
"math/rand"
"time"
)

var defaultRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))

func test(index int) {
for i := 0; i < 1000*10; i++ {
_ = defaultRand.Intn(20)
}
fmt.Println("done", index)
}

func main() {
for i := 0; i < 10; i++ {
go test(i)
}

time.Sleep(5 * time.Second)
fmt.Println("exit")
}

it works well when run only one goroutine


--
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/d/optout.

Search Discussions

  • Buzzlight at Sep 27, 2015 at 2:45 am
    it works well if call rand.New every times, but performance is bad.


    在 2015年9月27日星期日 UTC+8上午10:39:24,buzzlight写道:
    rand.Intn panic in goroutine, below is stack info

    panic: runtime error: index out of range

    goroutine 7 [running]:
    math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rng.go:244 +0xc1
    math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rand.go:46 +0x39
    math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
    /usr/local/go/src/math/rand/rand.go:52 +0x21
    math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:87 +0xc1
    math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:101 +0x92

    code is

    package main

    import (
    //"io"
    "fmt"
    "math/rand"
    "time"
    )

    var defaultRand *rand.Rand =
    rand.New(rand.NewSource(time.Now().UnixNano()))

    func test(index int) {
    for i := 0; i < 1000*10; i++ {
    _ = defaultRand.Intn(20)
    }
    fmt.Println("done", index)
    }

    func main() {
    for i := 0; i < 10; i++ {
    go test(i)
    }

    time.Sleep(5 * time.Second)
    fmt.Println("exit")
    }

    it works well when run only one goroutine

    --
    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/d/optout.
  • Chris Kastorff at Sep 27, 2015 at 2:57 am
    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.

    http://play.golang.org/p/vBHatu5Md3
    On Sat, Sep 26, 2015 at 7:45 PM, buzzlight wrote:
    it works well if call rand.New every times, but performance is bad.


    在 2015年9月27日星期日 UTC+8上午10:39:24,buzzlight写道:
    rand.Intn panic in goroutine, below is stack info

    panic: runtime error: index out of range

    goroutine 7 [running]:
    math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rng.go:244 +0xc1
    math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rand.go:46 +0x39
    math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
    /usr/local/go/src/math/rand/rand.go:52 +0x21
    math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:87 +0xc1
    math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:101 +0x92

    code is

    package main

    import (
    //"io"
    "fmt"
    "math/rand"
    "time"
    )

    var defaultRand *rand.Rand =
    rand.New(rand.NewSource(time.Now().UnixNano()))

    func test(index int) {
    for i := 0; i < 1000*10; i++ {
    _ = defaultRand.Intn(20)
    }
    fmt.Println("done", index)
    }

    func main() {
    for i := 0; i < 10; i++ {
    go test(i)
    }

    time.Sleep(5 * time.Second)
    fmt.Println("exit")
    }

    it works well when run only one goroutine
    --
    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/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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dianming Song at Sep 28, 2015 at 2:41 am
    how to create new Rand pre goroutine in a http server?

    2015-09-27 10:57 GMT+08:00 Chris Kastorff <encryptio@gmail.com>:
    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.

    http://play.golang.org/p/vBHatu5Md3
    On Sat, Sep 26, 2015 at 7:45 PM, buzzlight wrote:
    it works well if call rand.New every times, but performance is bad.


    在 2015年9月27日星期日 UTC+8上午10:39:24,buzzlight写道:
    rand.Intn panic in goroutine, below is stack info

    panic: runtime error: index out of range

    goroutine 7 [running]:
    math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rng.go:244 +0xc1
    math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rand.go:46 +0x39
    math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
    /usr/local/go/src/math/rand/rand.go:52 +0x21
    math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:87 +0xc1
    math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:101 +0x92

    code is

    package main

    import (
    //"io"
    "fmt"
    "math/rand"
    "time"
    )

    var defaultRand *rand.Rand =
    rand.New(rand.NewSource(time.Now().UnixNano()))

    func test(index int) {
    for i := 0; i < 1000*10; i++ {
    _ = defaultRand.Intn(20)
    }
    fmt.Println("done", index)
    }

    func main() {
    for i := 0; i < 10; i++ {
    go test(i)
    }

    time.Sleep(5 * time.Second)
    fmt.Println("exit")
    }

    it works well when run only one goroutine
    --
    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/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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Kastorff at Sep 28, 2015 at 3:17 am
    You could use a sync.Pool for this: https://golang.org/pkg/sync/#Pool
    - you can use it to make a pool of *rand.Rands which automatically
    resizes to match your concurrency load.

    Alternatively, if you want more control over the process: make a
    buffered chan *rand.Rand (no need to put anything in it.) When you
    need a Rand, use a nonblocking read to get an existing one if
    possible, and if not, initialize one. When you're done, use a
    nonblocking write to put it back into the chan (and drop it if the
    channel is full.) You can monitor how many times you hit the "drop it
    if the channel is full" branch if you want to know if the channel
    buffer is too small for your load.

    Since *rand.rngSource objects are pretty big (607 int64s and 2 ints; a
    little under 5K), you'll want to keep the number of extra sources you
    keep around to a minimum.

    Or you could implement a concurrency-safe rand.Source implementation.
    That seems tricky to do correctly, so it's probably better to do the
    pooling above unless you're seriously memory constrained.
    On Sun, Sep 27, 2015 at 7:40 PM, Dianming Song wrote:
    how to create new Rand pre goroutine in a http server?

    2015-09-27 10:57 GMT+08:00 Chris Kastorff <encryptio@gmail.com>:
    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.

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

    On Sat, Sep 26, 2015 at 7:45 PM, buzzlight <dianming.song@gmail.com>
    wrote:
    it works well if call rand.New every times, but performance is bad.


    在 2015年9月27日星期日 UTC+8上午10:39:24,buzzlight写道:
    rand.Intn panic in goroutine, below is stack info

    panic: runtime error: index out of range

    goroutine 7 [running]:
    math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rng.go:244 +0xc1
    math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rand.go:46 +0x39
    math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
    /usr/local/go/src/math/rand/rand.go:52 +0x21
    math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:87 +0xc1
    math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:101 +0x92

    code is

    package main

    import (
    //"io"
    "fmt"
    "math/rand"
    "time"
    )

    var defaultRand *rand.Rand =
    rand.New(rand.NewSource(time.Now().UnixNano()))

    func test(index int) {
    for i := 0; i < 1000*10; i++ {
    _ = defaultRand.Intn(20)
    }
    fmt.Println("done", index)
    }

    func main() {
    for i := 0; i < 10; i++ {
    go test(i)
    }

    time.Sleep(5 * time.Second)
    fmt.Println("exit")
    }

    it works well when run only one goroutine
    --
    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/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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nick Craig-Wood at Sep 28, 2015 at 11:12 am
    Or you could start a goroutine which pumps random numbers into a
    (buffered) channel - that is easy and might work for you.
    On 28/09/15 04:17, Chris Kastorff wrote:
    You could use a sync.Pool for this: https://golang.org/pkg/sync/#Pool
    - you can use it to make a pool of *rand.Rands which automatically
    resizes to match your concurrency load.

    Alternatively, if you want more control over the process: make a
    buffered chan *rand.Rand (no need to put anything in it.) When you
    need a Rand, use a nonblocking read to get an existing one if
    possible, and if not, initialize one. When you're done, use a
    nonblocking write to put it back into the chan (and drop it if the
    channel is full.) You can monitor how many times you hit the "drop it
    if the channel is full" branch if you want to know if the channel
    buffer is too small for your load.

    Since *rand.rngSource objects are pretty big (607 int64s and 2 ints; a
    little under 5K), you'll want to keep the number of extra sources you
    keep around to a minimum.

    Or you could implement a concurrency-safe rand.Source implementation.
    That seems tricky to do correctly, so it's probably better to do the
    pooling above unless you're seriously memory constrained.
    On Sun, Sep 27, 2015 at 7:40 PM, Dianming Song wrote:
    how to create new Rand pre goroutine in a http server?

    2015-09-27 10:57 GMT+08:00 Chris Kastorff <encryptio@gmail.com>:
    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.

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

    On Sat, Sep 26, 2015 at 7:45 PM, buzzlight <dianming.song@gmail.com>
    wrote:
    it works well if call rand.New every times, but performance is bad.


    在 2015年9月27日星期日 UTC+8上午10:39:24,buzzlight写道:
    rand.Intn panic in goroutine, below is stack info

    panic: runtime error: index out of range

    goroutine 7 [running]:
    math/rand.(*rngSource).Int63(0x820200a00, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rng.go:244 +0xc1
    math/rand.(*Rand).Int63(0x8201e8320, 0x2a4ec0830e6a2d28)
    /usr/local/go/src/math/rand/rand.go:46 +0x39
    math/rand.(*Rand).Int31(0x8201e8320, 0x2a4ec083)
    /usr/local/go/src/math/rand/rand.go:52 +0x21
    math/rand.(*Rand).Int31n(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:87 +0xc1
    math/rand.(*Rand).Intn(0x8201e8320, 0x14, 0x3)
    /usr/local/go/src/math/rand/rand.go:101 +0x92

    code is

    package main

    import (
    //"io"
    "fmt"
    "math/rand"
    "time"
    )

    var defaultRand *rand.Rand =
    rand.New(rand.NewSource(time.Now().UnixNano()))

    func test(index int) {
    for i := 0; i < 1000*10; i++ {
    _ = defaultRand.Intn(20)
    }
    fmt.Println("done", index)
    }

    func main() {
    for i := 0; i < 10; i++ {
    go test(i)
    }

    time.Sleep(5 * time.Second)
    fmt.Println("exit")
    }

    it works well when run only one goroutine
    --
    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/d/optout.

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    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/d/optout.
  • Clark Wierda at Jan 5, 2016 at 6:14 am
    From the package documentation: The default Source is safe for concurrent
    use by multiple goroutines.

    I understood this to include instances of NewSource as well. I now know
    that this is incorrect. Sources *can* be safe for concurrent access, but
    they do not have to be.

    I think a note to the effect that NewSource is not inherently safe for
    concurrent access should be added to its documentation.
    On Saturday, September 26, 2015 at 10:58:11 PM UTC-4, Chris Kastorff wrote:

    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.
    --
    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/d/optout.
  • Michael Jones at Jan 5, 2016 at 12:08 pm
    The meta-issue deserves to be clear as well—something dynamic that is concurrency-safe must be serializing internally at a performance cost that is likely to become a performance problem at scale. Something not-safe is “raw” and can run as fast as possible in its lone, non-concurrent context. These two aspects frame the issue.


    Michael Jones, CEO • michael@wearality.com • +1 650 656-6989
    Wearality Corporation • 289 S. San Antonio Road • Los Altos, CA 94022
    On Jan 4, 2016, at 7:27 PM, Clark Wierda wrote:

    From the package documentation: The default Source is safe for concurrent use by multiple goroutines.

    I understood this to include instances of NewSource as well. I now know that this is incorrect. Sources can be safe for concurrent access, but they do not have to be.

    I think a note to the effect that NewSource is not inherently safe for concurrent access should be added to its documentation.

    On Saturday, September 26, 2015 at 10:58:11 PM UTC-4, Chris Kastorff wrote:
    rand.Rand is not safe for concurrent access. Create a new rand.Rand
    per goroutine; you don't have to do it on every Intn call, just enough
    to avoid concurrent access.


    --
    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/d/optout <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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Clark Wierda at Jan 5, 2016 at 8:40 pm
    I found comments about the concurrency-safe aspect of top-level functions
    in packages. Included was a comment that lower-level function in that
    package should not be considered concurrency-safe unless specifically
    indicated as such.

    This is consistent, provides the capability you address regarding
    performance, and is in line with my experience with the packages I've used
    so far.

    What I don't know is where this information on the general expectation
    should be in the Golang documentation. Since it is more general (and the
    math/rand package is consistent with the rest), I don't feel a special
    mention is needed in the package. [I've done some more research since my
    earlier post.] But, as a new user, where would I be expected to have found
    this information on what I should expect regarding features of the packages
    and the functions they contain?

    Clark B. Wierda
    Go student, entering the "know enough to be dangerous" stage
    Currently leaning more about performance evaluation and improvement
    On Tuesday, January 5, 2016 at 7:08:50 AM UTC-5, Michael Jones wrote:

    The meta-issue deserves to be clear as well—something dynamic that is
    concurrency-safe must be serializing internally at a performance cost that
    is likely to become a performance problem at scale. Something not-safe is
    “raw” and can run as fast as possible in its lone, non-concurrent context.
    These two aspects frame the issue.


    Michael Jones, CEO • mic...@wearality.com <javascript:> • +1 650
    656-6989
    Wearality Corporation • 289 S. San Antonio Road • Los Altos, CA 94022
    --
    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/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedSep 27, '15 at 2:39a
activeJan 5, '16 at 8:40p
posts9
users5
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase