Menu
Coddy logo textTech

Goroutines Basics

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 59 of 107.

A goroutine is a lightweight thread of execution managed by the Go runtime. Unlike traditional threads that consume significant memory, goroutines start with just a few kilobytes of stack space, allowing you to run thousands of them concurrently.

To start a goroutine, simply place the go keyword before a function call:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // runs concurrently
    go sayHello("Bob")    // runs concurrently
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

When go sayHello("Alice") executes, it doesn't wait for sayHello to finish. Instead, it immediately continues to the next line while sayHello runs in the background. This is why we need time.Sleep—without it, main would exit before the goroutines complete.

You can also launch goroutines with anonymous functions:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

The main function itself runs in a goroutine. When it returns, all other goroutines are terminated immediately—they don't get a chance to finish. Using time.Sleep is a temporary solution; in the upcoming lessons, you'll learn proper synchronization techniques with channels and wait groups.

challenge icon

Challenge

Easy

Let's build a task runner that executes multiple tasks concurrently using goroutines. You'll create a simple system where tasks run in the background while the main program continues, demonstrating how goroutines enable concurrent execution.

You'll organize your code across two files:

  • tasks.go: Define your task execution logic.

    Create a Task struct with Name (string) and Duration (int, representing milliseconds) fields.

    Implement a method Run() on Task that simulates work by sleeping for the task's duration, then prints: Task [Name] completed

    Create a function RunAllTasks(tasks []Task) that launches each task's Run() method as a goroutine. After launching all goroutines, it should sleep for 500 milliseconds to allow them to complete, then print: All tasks launched

  • main.go: Read task information and orchestrate the concurrent execution.

    Read the number of tasks, then read each task's name and duration. Create the tasks and pass them to RunAllTasks. After it returns, print: Main function done

The following inputs will be provided:

  • Line 1: Number of tasks (integer)
  • Following lines: For each task, two lines - the task name, then its duration in milliseconds

For example, given:

3
Download
100
Process
50
Upload
75

Your output should show tasks completing (order may vary due to concurrency), followed by the completion messages:

Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function done

Note: Since goroutines run concurrently, tasks with shorter durations typically finish first. The task completion order depends on their durations - shorter tasks complete before longer ones.

Use time.Sleep with time.Duration and time.Millisecond for the delays. Remember that without the sleep in RunAllTasks, the function would return before goroutines finish their work.

Cheat sheet

A goroutine is a lightweight thread of execution managed by the Go runtime. Goroutines start with just a few kilobytes of stack space, allowing you to run thousands of them concurrently.

To start a goroutine, place the go keyword before a function call:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // runs concurrently
    go sayHello("Bob")    // runs concurrently
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

When go sayHello("Alice") executes, it doesn't wait for sayHello to finish. Instead, it immediately continues to the next line while sayHello runs in the background.

You can launch goroutines with anonymous functions:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

The main function itself runs in a goroutine. When it returns, all other goroutines are terminated immediately. Use time.Sleep to allow goroutines to complete before the main function exits.

Try it yourself

package main

import (
	"fmt"
)

func main() {
	// Read the number of tasks
	var numTasks int
	fmt.Scanln(&numTasks)

	// TODO: Create a slice to hold the tasks
	
	// TODO: Read each task's name and duration
	// For each task:
	//   - Read the task name
	//   - Read the duration (as integer)
	//   - Create a Task and append to your slice

	// TODO: Call RunAllTasks with your tasks slice

	// TODO: Print "Main function done"
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming