Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAnthony Albertorio
22,624 PointsMy notes on channels
package main
import (
"fmt"
"math/rand"
"time"
)
func longTask(channel chan int) { // type chan, type chan holds is int. No return value
delay := rand.Intn(5) // get random number
fmt.Println("Starting long task")
time.Sleep(time.Duration(delay) * time.Second) // sleeps random number of seconds
fmt.Println("Long task finished")
// return delay // return doesn't work with goroutines
channel <- delay // delay INTO channel
}
func main() {
rand.Seed(time.Now().Unix())
// time := longTask() // old linear way
// time := go longTask() // error: unexpected go, expects expression
channel := make(chan int)
go longTask(channel)
// read from channel causes main goroutine to wait
// until longTask() goroutine finishes.
// Solves problem of main() goroutine exiting before longTask() done
// Communicates between routines, and synches them up
fmt.Println("Took", <-channel, "seconds") // read value from channel
// arrow pointing FROM channel INTO your code
// or channel INTO code
// multiple goroutines can write to same channel
for i := 1;i <= 3; i++ {
go longTask(channel) // call longTask() 3x goroutines
}
for i := 1; i <= 3; i++ {
// Because we read from channel
// the same number of times we wrote to it,
// the program aka main(),
// waits till GoRoutines have finished before it exits
fmt.Println("Took", <-channel, "seconds")
}
}
/*
Notes:
channels - 1. lets go routines communicate with each other
2. synchronizes go routines
Issue:
Not possible to communicate between go routines using return values.
go routine 1 can't return value that go routine 2 can use uses.
Go Routines suffer from familiar asynchronous programming issues.
Code is sequential, but returns are asynchronous.
JavaScript fixes this with promises and async/await.
Solution:
Go uses channels.
similarities:
go -> async
channel -> await.
When main go routine encounters channel,
it waits until it has a value to proceed.
Differences compared to JavaScript/NodeJS:
1. Go is deep coroutines. Pausing them captures the entire stack
A calls B.
B calls C.
C is able to stop execution of A.
A -> B -> C. C can stop A.
JavaScript is shallow coroutines. Pausing them only captures
the current function's stack
A calls B
B calls C
C is only able to stop C. Not A or B.
See:
https://www.quora.com/Is-async-await-in-Node-js-similar-to-Goroutines
2. Instead of sharing global state,
the coroutines communicate state through channels
5. NodeJS is single threaded
NodeJS implements a simple form of concurrency
thru non-blocking I/O (input/output)
It doesn't block other computation from happening
while waiting for values.
async/await and Promises are abstractions on top of this.
So NodeJS is only async I/O (input/output)
Go is multi threaded.
Go supports true concurrency with access to CPU cores.
Not only async I/I(input/output).
If goroutines takes extra CPU time,
it will move data to different CPU threads
and is still executed.
see: https://codeburst.io/why-goroutines-are-not-lightweight-threads-7c460c1f155f
syntax:
chan - channel
channel := make(chan int) - make channel with int value it will accept
<- - The <- operator means put or get message from a channel.
The <- operator represents the idea of passing a value
from a channel to a reference.
Think of the channel as a queue.
Using an assignment operator = would assign the reference to the queue
to the target variable.
The receive operator <- is equivalent to dequeuing from the queue
and assigning the value of the item to the target variable.
<-channel - read value from channel
Difference between = and <- in GoLang:
https://stackoverflow.com/questions/33325395/what-is-the-difference-between-and-in-golang
How to write common JS code in Go:
see: https://levelup.gitconnected.com/use-go-channels-as-promises-and-async-await-ee62d93078ec
*/