FAQ
Dear All,

I modify the tour sample of channel(http://tour.golang.org/#66) to confirm
if the channel feature runs as i think.

But i'm not very sure.

Which friend can explain the output result?

*channel.go*
package main

import "fmt"

func fibonacci(c, quit chan int) {
fmt.Println("fibonacci start")
x, y := 0, 1

for {
fmt.Println("set c", x)
c <- x
fmt.Println("AFTER SET c")
x, y = y, x+y
}
fmt.Println("fibonacci end")
}

func main() {
c := make(chan int)
quit := make(chan int)

go fibonacci(c, quit)
go func() {
fmt.Println("func start")
for i := 0; i < 10; i++ {
fmt.Println("get c", <-c)
fmt.Println("AFTER GET c")
}
fmt.Println("func, outside for.")
fmt.Println(<-c)
quit <- 1
fmt.Println("func end")
}()

fmt.Println(<-quit)
}

*output:*
fibonacci start
set c 0
func start
get c 0
AFTER GET c
AFTER SET c
set c 1
AFTER SET c
set c 1
get c 1
AFTER GET c
get c 1
AFTER GET c
AFTER SET c
set c 2
AFTER SET c
set c 3
get c 2
AFTER GET c
get c 3
AFTER GET c
AFTER SET c
set c 5
AFTER SET c
set c 8
get c 5
AFTER GET c
get c 8
AFTER GET c
AFTER SET c
set c 13
AFTER SET c
set c 21
get c 13
AFTER GET c
get c 21
AFTER GET c
AFTER SET c
set c 34
AFTER SET c
set c 55
get c 34
AFTER GET c
func, outside for.
55
func end
AFTER SET c
set c 89
1

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

  • Péter Szilágyi at Apr 9, 2013 at 12:57 pm
    And what is your question? You have two threads, one producer and one
    consumer communicating through a channel which you can follow with the
    set/get pairs + some test outputs. Since your go routines are ran
    concurrently (actually scheduled) you have a slight variance in the order
    in which the texts between the two goroutines are displayed.

    On Tue, Apr 9, 2013 at 12:05 PM, kingfly lion wrote:

    Dear All,

    I modify the tour sample of channel(http://tour.golang.org/#66) to
    confirm if the channel feature runs as i think.

    But i'm not very sure.

    Which friend can explain the output result?

    *channel.go*
    package main

    import "fmt"

    func fibonacci(c, quit chan int) {
    fmt.Println("fibonacci start")
    x, y := 0, 1

    for {
    fmt.Println("set c", x)
    c <- x
    fmt.Println("AFTER SET c")
    x, y = y, x+y
    }
    fmt.Println("fibonacci end")
    }

    func main() {
    c := make(chan int)
    quit := make(chan int)

    go fibonacci(c, quit)
    go func() {
    fmt.Println("func start")
    for i := 0; i < 10; i++ {
    fmt.Println("get c", <-c)
    fmt.Println("AFTER GET c")
    }
    fmt.Println("func, outside for.")
    fmt.Println(<-c)
    quit <- 1
    fmt.Println("func end")
    }()

    fmt.Println(<-quit)
    }

    *output:*
    fibonacci start
    set c 0
    func start
    get c 0
    AFTER GET c
    AFTER SET c
    set c 1
    AFTER SET c
    set c 1
    get c 1
    AFTER GET c
    get c 1
    AFTER GET c
    AFTER SET c
    set c 2
    AFTER SET c
    set c 3
    get c 2
    AFTER GET c
    get c 3
    AFTER GET c
    AFTER SET c
    set c 5
    AFTER SET c
    set c 8
    get c 5
    AFTER GET c
    get c 8
    AFTER GET c
    AFTER SET c
    set c 13
    AFTER SET c
    set c 21
    get c 13
    AFTER GET c
    get c 21
    AFTER GET c
    AFTER SET c
    set c 34
    AFTER SET c
    set c 55
    get c 34
    AFTER GET c
    func, outside for.
    55
    func end
    AFTER SET c
    set c 89
    1

    --
    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.
  • Alex martin at Apr 9, 2013 at 9:18 pm
    I think that question was this:
    If the channel is synchronized why we have the repetition of this

    *set c 1*
    AFTER SET c
    *set c 1*
    *get c 1*
    AFTER GET c
    *get c 1*

    without set/AFTER Println all works fine


    On Tuesday, April 9, 2013 2:57:01 PM UTC+2, Péter Szilágyi wrote:

    And what is your question? You have two threads, one producer and one
    consumer communicating through a channel which you can follow with the
    set/get pairs + some test outputs. Since your go routines are ran
    concurrently (actually scheduled) you have a slight variance in the order
    in which the texts between the two goroutines are displayed.


    On Tue, Apr 9, 2013 at 12:05 PM, kingfly lion <lionk...@gmail.com<javascript:>
    wrote:
    Dear All,

    I modify the tour sample of channel(http://tour.golang.org/#66) to
    confirm if the channel feature runs as i think.

    But i'm not very sure.

    Which friend can explain the output result?

    *channel.go*
    package main

    import "fmt"

    func fibonacci(c, quit chan int) {
    fmt.Println("fibonacci start")
    x, y := 0, 1

    for {
    fmt.Println("set c", x)
    c <- x
    fmt.Println("AFTER SET c")
    x, y = y, x+y
    }
    fmt.Println("fibonacci end")
    }

    func main() {
    c := make(chan int)
    quit := make(chan int)

    go fibonacci(c, quit)
    go func() {
    fmt.Println("func start")
    for i := 0; i < 10; i++ {
    fmt.Println("get c", <-c)
    fmt.Println("AFTER GET c")
    }
    fmt.Println("func, outside for.")
    fmt.Println(<-c)
    quit <- 1
    fmt.Println("func end")
    }()

    fmt.Println(<-quit)
    }

    *output:*
    fibonacci start
    set c 0
    func start
    get c 0
    AFTER GET c
    AFTER SET c
    set c 1
    AFTER SET c
    set c 1
    get c 1
    AFTER GET c
    get c 1
    AFTER GET c
    AFTER SET c
    set c 2
    AFTER SET c
    set c 3
    get c 2
    AFTER GET c
    get c 3
    AFTER GET c
    AFTER SET c
    set c 5
    AFTER SET c
    set c 8
    get c 5
    AFTER GET c
    get c 8
    AFTER GET c
    AFTER SET c
    set c 13
    AFTER SET c
    set c 21
    get c 13
    AFTER GET c
    get c 21
    AFTER GET c
    AFTER SET c
    set c 34
    AFTER SET c
    set c 55
    get c 34
    AFTER GET c
    func, outside for.
    55
    func end
    AFTER SET c
    set c 89
    1

    --
    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.
  • Péter Szilágyi at Apr 9, 2013 at 10:17 pm
    Because the Fibbonacci sequence is 1, 1, 2, 3, 5, 8, ,,, ? :P

    On Tue, Apr 9, 2013 at 11:18 PM, alex martin wrote:

    I think that question was this:
    If the channel is synchronized why we have the repetition of this


    *set c 1*
    AFTER SET c
    *set c 1*
    *get c 1*
    AFTER GET c
    *get c 1*

    without set/AFTER Println all works fine


    On Tuesday, April 9, 2013 2:57:01 PM UTC+2, Péter Szilágyi wrote:

    And what is your question? You have two threads, one producer and one
    consumer communicating through a channel which you can follow with the
    set/get pairs + some test outputs. Since your go routines are ran
    concurrently (actually scheduled) you have a slight variance in the order
    in which the texts between the two goroutines are displayed.

    On Tue, Apr 9, 2013 at 12:05 PM, kingfly lion wrote:

    Dear All,

    I modify the tour sample of channel(http://tour.golang.**org/#66<http://tour.golang.org/#66>)
    to confirm if the channel feature runs as i think.

    But i'm not very sure.

    Which friend can explain the output result?

    *channel.go*
    package main

    import "fmt"

    func fibonacci(c, quit chan int) {
    fmt.Println("fibonacci start")
    x, y := 0, 1

    for {
    fmt.Println("set c", x)
    c <- x
    fmt.Println("AFTER SET c")
    x, y = y, x+y
    }
    fmt.Println("fibonacci end")
    }

    func main() {
    c := make(chan int)
    quit := make(chan int)

    go fibonacci(c, quit)
    go func() {
    fmt.Println("func start")
    for i := 0; i < 10; i++ {
    fmt.Println("get c", <-c)
    fmt.Println("AFTER GET c")
    }
    fmt.Println("func, outside for.")
    fmt.Println(<-c)
    quit <- 1
    fmt.Println("func end")
    }()

    fmt.Println(<-quit)
    }

    *output:*
    fibonacci start
    set c 0
    func start
    get c 0
    AFTER GET c
    AFTER SET c
    set c 1
    AFTER SET c
    set c 1
    get c 1
    AFTER GET c
    get c 1
    AFTER GET c
    AFTER SET c
    set c 2
    AFTER SET c
    set c 3
    get c 2
    AFTER GET c
    get c 3
    AFTER GET c
    AFTER SET c
    set c 5
    AFTER SET c
    set c 8
    get c 5
    AFTER GET c
    get c 8
    AFTER GET c
    AFTER SET c
    set c 13
    AFTER SET c
    set c 21
    get c 13
    AFTER GET c
    get c 21
    AFTER GET c
    AFTER SET c
    set c 34
    AFTER SET c
    set c 55
    get c 34
    AFTER GET c
    func, outside for.
    55
    func end
    AFTER SET c
    set c 89
    1

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

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

    --
    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.
  • Alex martin at Apr 9, 2013 at 10:32 pm
    LOL.. too much synchronization's problems today for me .... sorry for
    wasted time

    thank Péter
    On Wednesday, April 10, 2013 12:17:54 AM UTC+2, Péter Szilágyi wrote:

    Because the Fibbonacci sequence is 1, 1, 2, 3, 5, 8, ,,, ? :P


    --
    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.
  • Péter Szilágyi at Apr 10, 2013 at 8:42 am
    Hi,

    Yes, in general the program follows your thought line, but you have one
    slight error in it:

    When you send a number into the channel (i.e. line 11, c <- x), if there
    is a reader on the other side, then both go routines are allowed to
    continue. Thus one will be at "AFTER SET c" and the other inside the fmt.
    But the order here is unspecified, as in the scheduler gets to choose which
    to run and which to stop (or if you're running on multiple cores then they
    can even run concurrently). This means, that you have no control over the
    order of events (function calls) in two concurrent threads.

    So when you're seeing "set c 1", "set c 1", get c 1" (or later "set c 5",
    "set c 8", "get c 5") what actually is happening that:

    1. Reader blocks on "<-c" while evaluating the arguments to fmt-"get c"
    2. Writer prints first value "set c 1"
    3. Writer sends in first value c <- 1
    4. Writer would block, but reader can get it out, so it's not suspended
    5. Reader got the "<-c", so is resumed
    6. Here the scheduler has to make a decision: suspend the writer(fibbo
    generator) and run the reader OR keep the reader suspended and continue
    with the writer
    7. The scheduler chose to allow the writer to continue
    8. Writer prints "AFTER SET c"
    9. Writer calculates new number
    10. Writer prints second value "set c 1" (again number 1, remember the
    sequence is 1, 1, 2, 3, 5, 8, ...)
    11. Writer sends in second value c <- 1
    12. Nobody to read the value, writer blocks
    13. Scheduler has only the reader to allow, continues it thus
    14. Reader got the first one and was suspended in the middle of fmt
    argument evaluation, so it continues from there
    15. Reader prints "set c 1" (this was the first 1)
    16. Reader tries to get another number from c, and since the second 1 is
    inside, it gets it
    17. Now again, both are unblocked, scheduler has to choose
    18. Etc.

    The channel is the synchronization point. Your only guarantee is that
    both threads will wait there for each other. Other than than, each thread
    will happily race with the other in their doings.

    Hope this clears it up a bit :)

    Cheers,
    Peter

    On Wed, Apr 10, 2013 at 5:11 AM, lionkingfly wrote:

    nice peter, thanks.



    Here are my understandings about the code. Please advice me if they are
    right.
    1. line 22, 23, create two goroutines (A goroutine - fibonacci and B
    goroutine - func), immediately return to main thread, line 35, <-quit
    makes block, quit channel is ready to receive value int. As main thread is
    blocked, scheduler lets A goroutine run before B goroutine by the order of
    creation.

    2. line 11, send x to channel c(no buffer), makes block, (scheduler runs
    main thread line 35, check quit channel but is still blocked, I'm not
    sure about this) then run B goroutine.

    3. line 26, <-c, as channel c is ready to be received, print its value,
    then run to line 26 again, now <-c makes channel c block *but ready to
    receive*, Run A gorountie, back to line 11(Need some check? or run to
    line 12 directly?), print AFTER SET c, set c 1.

    4. *main confusion is now,* line 11, send x(1) to channel c but no block
    happened(because it's ready to receive, the value stored in channel c),
    print AFTER SET c, set c 1, then again to line 11, again send x(1) to
    channel c but currently block happened(How the channel do this? currently
    where this value stored? cache but only change the status of the channel?)

    ...


    于 2013/4/9 20:57, Péter Szilágyi 写道:

    And what is your question? You have two threads, one producer and one
    consumer communicating through a channel which you can follow with the
    set/get pairs + some test outputs. Since your go routines are ran
    concurrently (actually scheduled) you have a slight variance in the order
    in which the texts between the two goroutines are displayed.

    On Tue, Apr 9, 2013 at 12:05 PM, kingfly lion wrote:

    Dear All,

    I modify the tour sample of channel(http://tour.golang.org/#66) to
    confirm if the channel feature runs as i think.

    But i'm not very sure.

    Which friend can explain the output result?

    *channel.go*
    package main

    import "fmt"

    func fibonacci(c, quit chan int) {
    fmt.Println("fibonacci start")
    x, y := 0, 1

    for {
    fmt.Println("set c", x)
    c <- x
    fmt.Println("AFTER SET c")
    x, y = y, x+y
    }
    fmt.Println("fibonacci end")
    }

    func main() {
    c := make(chan int)
    quit := make(chan int)

    go fibonacci(c, quit)
    go func() {
    fmt.Println("func start")
    for i := 0; i < 10; i++ {
    fmt.Println("get c", <-c)
    fmt.Println("AFTER GET c")
    }
    fmt.Println("func, outside for.")
    fmt.Println(<-c)
    quit <- 1
    fmt.Println("func end")
    }()

    fmt.Println(<-quit)
    }

    *output:*
    fibonacci start
    set c 0
    func start
    get c 0
    AFTER GET c
    AFTER SET c
    set c 1
    AFTER SET c
    set c 1
    get c 1
    AFTER GET c
    get c 1
    AFTER GET c
    AFTER SET c
    set c 2
    AFTER SET c
    set c 3
    get c 2
    AFTER GET c
    get c 3
    AFTER GET c
    AFTER SET c
    set c 5
    AFTER SET c
    set c 8
    get c 5
    AFTER GET c
    get c 8
    AFTER GET c
    AFTER SET c
    set c 13
    AFTER SET c
    set c 21
    get c 13
    AFTER GET c
    get c 21
    AFTER GET c
    AFTER SET c
    set c 34
    AFTER SET c
    set c 55
    get c 34
    AFTER GET c
    func, outside for.
    55
    func end
    AFTER SET c
    set c 89
    1
    --
    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
postedApr 9, '13 at 12:37p
activeApr 10, '13 at 8:42a
posts6
users3
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase