简体   繁体   中英

Ordering of senders in a Go channel

Consider the ping pong example from http://www.golang-book.com/10/index.htm#section2 .

package main

import (
    "fmt"
    "time"
)

func pinger(c chan string) {
    for i := 0; ; i++ {
        c <- "ping"
    }
}

func ponger(c chan string) {
    for i := 0; ; i++ {
        c <- "pong"
    }
}

func printer(c chan string) {
    for {
        msg := <- c
        fmt.Println(msg)
        time.Sleep(time.Second * 1)
    }
}

func main() {
    var c chan string = make(chan string)

    go pinger(c)
    go ponger(c)
    go printer(c)

    var input string
    fmt.Scanln(&input)
}

The authors write:

"The program will now take turns printing ping and pong."

However, for this to be true, Go must decide on an order in which senders can send into a channel? Otherwise, there would be no guarantee that a ping would be sent before a pong (ie you can't get two pings, or two pongs in a row). How does this work?

There is no synchronization between the ping and pong goroutines, therefore there is no guarantee that the responses will print in order.

If you force the goroutines to race with GOMAXPROCS>1, you get random output:

pong
ping
ping
pong
ping
pong
ping
pong
pong

This isn't even an example of a "ping-pong", since there's is no call and response.

There was a related question on the order of selection of messages entering a channel recently.

The answer is that the order is normally non-deterministic . This is intentional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM