As I mention in my first post, I am learning a bit of Go. Today, I came across goroutines, which are essentially functions or methods that run concurrently, in a “thread”-like way.
So if we have the (very basic) code:
func main() {
go makeSureBothStatementsGetInThere()
fmt.Println("We are executed concurrently.")
}
func makeSureBothStatementsGetInThere() {
fmt.Println("We are executed concurrently.")
}
what will happen is that go will invoke makeSureBothStatementsGetInThere() concurrently with the fmt.Println statement below it. Thus, it is possible to have one statement print to the screen or both statements print to the screen. We won’t know in advance.
That’s where channels come in:
func main() {
quitSignal := make(chan bool)
go makeSureBothStatementsGetInThere(quitSignal)
fmt.Println("We are executed concurrently.")
<-quitSignal
}
func makeSureBothStatementsGetInThere(channel chan bool) {
fmt.Println("We are executed concurrently.")
channel <- true
}
Now the program will await the quitSignal before exiting, ensuring both statements are printed to the screen.
I think this is a pretty simple way to do a very complicated task (i.e., threading, essentially). Go seems kinda neat.
[UPDATE] I’ve delved a bit deeper into goroutines, and I’ve learned a design pattern, which seems to be incredibly useful in Go application design. Suppose you have a lot of code in an application, which you want to run concurrently with the rest of your application. One way to do it would be to use a “goroutine generator.”
We define a function waitThenSend():
func waitThenSend(i, value int) chan int {
channel := make(chan int)
go func() {
time.Sleep(time.Duration(i) * time.Second)
channel <- value
}()
return channel
}
This can be called in our main() function, like so:
func main() {
fmt.Println(<-waitThenSend(3, 42))
}
What will happen? The program will wait for three seconds, and then it will print out the integer 42. By using this pattern, we can put any code we want to run concurrently inside the generator function’s goroutine and then simply call the generator function when needed.
Very interesting and, I’m sure, incredibly useful.