Concurrency with Goroutines

Photo by Peggy Anke on Unsplash

Concurrency with Goroutines

Let us modify the simple blink program from our earlier tutorial to run multiple tasks simultaneously. This is what we call concurrency.

Go has a number of primitives to help make programmers' lives easier when they create concurrent programs. In this tutorial, we will look at one of them, namely Goroutines.

The Program

The aim of our program is to do the following two things at once:

  1. Blink the onboard LED twice a second.
  2. Print the phrase "hello concurrently" to the serial (UART) port.

We modify the blink.go program from the earlier tutorial to add:

  1. A function (named printHello) that prints "hello concurrently" in an infinite loop.
  2. A goroutine that spawns this function so that it runs concurrent to the main thread that is blinking the LED.
// ConcurrentBlink.go

package main

import (
    "machine"
    "time"
)

func main() {
    led := machine.LED
    led.Configure(machine.PinConfig{
        Mode: machine.PinOutput,
    })

    go printHello()

    for {
        led.High()
        time.Sleep(500 * time.Millisecond)
        led.Low()
        time.Sleep(500 * time.Millisecond)
    }
}

func printHello() {
    for {
        println("hello concurrently")
        time.Sleep(time.Second)
    }
}

Testing the Program

Ensure that your serial debugger is set up as described in my earlier tutorial on setting up the Pico for serial debugging.

Flash the program to your pico:

% tinygo flash -target=pico concurrentblink.go

You should see the onboard LED blinking, while the phrase "hello concurrently" is printed every second in the serial monitor.

References

  • Rob Pike's presentation on "Concurrency is not parallelism".