Sling Academy
Home/Golang/The `runtime.NumGoroutine`: Monitoring Goroutines in Go

The `runtime.NumGoroutine`: Monitoring Goroutines in Go

Last updated: November 27, 2024

Go, also known as Golang, is a statically typed, compiled programming language developed by Google. It is known for its simplicity, performance, and concurrency capabilities. One of the key features of Go's concurrency model are goroutines, which are lightweight threads managed by the Go runtime. In this article, we'll explore how to monitor the number of goroutines using Go's runtime package, specifically focusing on the runtime.NumGoroutine function.

What are Goroutines?

Goroutines are functions or methods that run concurrently with other functions or methods. They are a lightweight abstraction, much cheaper than traditional threads, making concurrency safe and simple. You can start a goroutine using the go keyword followed by a function call:


go func sayHello() {
    fmt.Println("Hello, World!")
}

go sayHello()

Monitoring Goroutines with runtime.NumGoroutine

The runtime package in Go provides features to interact with the Go runtime system and programs. This package includes the function runtime.NumGoroutine which returns the number of currently existing goroutines.

Using runtime.NumGoroutine is valuable for analyzing how well your program is utilizing concurrency, monitoring performance, and detecting potential leaks where goroutines may not be terminating as expected.

Example: Using runtime.NumGoroutine

In this example, we'll create a few goroutines and monitor their count using runtime.NumGoroutine.


package main

import (
    "fmt"
    "runtime"
    "sync"
)

func worker(wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Println("Worker goroutine executing")
}

func main() {
    var wg sync.WaitGroup

    // Initially, there's just the main goroutine
    fmt.Println("Starting goroutine count:", runtime.NumGoroutine())

    // We launch several additional goroutines
    const numWorkers = 5
    wg.Add(numWorkers)
    for i := 1; i <= numWorkers; i++ {
        go worker(&wg)
    }

    // Print the number of goroutines after launching workers
    fmt.Println("Goroutines after starting workers:", runtime.NumGoroutine())

    // Wait for all workers to finish
    wg.Wait()

    // Print the final number of goroutines
    fmt.Println("Final goroutine count:", runtime.NumGoroutine())
}

In this code:

  • We import the runtime and sync packages to use runtime.NumGoroutine and wait group features.
  • A worker function simulates a task and uses wg.Done() to indicate completion.
  • We create multiple worker goroutines and print the number of goroutines before and after their execution.
  • Finally, we print the number of goroutines left running, ensuring all workers have completed.

Understanding the Output

When you run the above example, you might see output similar to:


Starting goroutine count: 1
Worker goroutine executing
Worker goroutine executing
Worker goroutine executing
Worker goroutine executing
Worker goroutine executing
Goroutines after starting workers: 6
Final goroutine count: 1

The "Starting goroutine count" and "Final goroutine count" typically return 1, as the main goroutine is always running. The "Goroutines after starting workers" reflects the additional worker goroutines running concurrently.

Conclusion

By using runtime.NumGoroutine, developers can perform valuable diagnostics and optimizations in Go applications that leverage concurrency. This function is a handy tool for keeping tabs on goroutine usage and ensuring that they are not growing unexpectedly, which can be indicative of improper goroutine management.

Next Article: Building Concurrent Web Scrapers with Go

Previous Article: The `runtime.Gosched` Function: Yielding Execution in Go

Series: Concurrency and Synchronization in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant