Go Channel – My code looks overwriting channels but works.

Issue

I just started learning Go recently and I was confused when I learning Goroutine.
Here’s my code. This intends to finish 3 processes concurrently.

package main

import (
    "fmt"
    "log"
    "time"
)

func wait1(c chan string) {
    time.Sleep(1 * time.Second)
    log.Print("waited 1 sec")
    c <- "wait1 finished\n"

}

func wait2(c chan string) {
    time.Sleep(2 * time.Second)
    log.Print("waited 2 sec")
    c <- "wait2 finished\n"
}

func wait3(c chan string) {
    time.Sleep(3 * time.Second)
    log.Print("waited 3 sec")
    c <- "wait3 finished\n"
}

func main() {
    c := make(chan string, 3)
    log.Print("started")
    go wait1(c)
    go wait2(c)
    go wait3(c)
    w1, w2, w3 := <-c, <-c, <-c
    log.Print("finished")
    fmt.Println(w1, w2, w3)
}

For me, this part looks inputting different functions into the same channel called c and trying to print the values received from c.

c := make(chan string, 3)
log.Print("started")
go wait1(c)
go wait2(c)
go wait3(c)
w1, w2, w3 := <-c, <-c, <-c
log.Print("finished")
fmt.Println(w1, w2, w3)

However, as you can see, output is what I expected. It processes 3 functions at the same time and returns “finished” statement.

2015/11/25 09:41:31 started
2015/11/25 09:41:32 waited 1 sec
2015/11/25 09:41:33 waited 2 sec
2015/11/25 09:41:34 waited 3 sec
2015/11/25 09:41:34 finished
wait1 finished
wait2 finished
wait3 finished

Why it’s unnecessary to create 3 different channels like c1, c2, c3…?
Why value is not overwritten even though I’m using the same channel called c?

Solution

As far as I understood, you view channels as a variable. A variable that can hold some value. So if there was some value1 and you wrote another value2 you basically expect the value1 to disappear. Which is wrong.

Try to take a look at the channels as a buffer or a priority queue (some people find it crude comparison). Channel has it’s size (your third variable 3) which tells how many values can be simultaneously in it. Once you put something in the channel, you can view it as being processes with the priority equal to amount of time needed to finish this go-routine.

So in your case you put 3 elements in your priority queue with go wait() and then extracted from a queue with w1, w2, w3 := <-c, <-c, <-c. So nothing gets overwritten.

Answered By – Salvador Dali

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.