DEV Community

Ankit malik
Ankit malik

Posted on

What is Goroutine

Introduction

A goroutine is essentially a lightweight thread of execution that is managed by the Go runtime. Unlike traditional threads, which are managed by the operating system, goroutines are managed entirely within the Go runtime and are much more lightweight and efficient. Goroutines are designed to make it easy to write highly concurrent programs that can handle many tasks at once.

How Goroutines Work

To create a goroutine in Go, you simply use the go keyword followed by a function call. Here's an example:

package main

import (
    "fmt"
    "time"
)

func main() {
    go sayHello()
    go sayGoodbye()

    // Wait for goroutines to finish executing
    time.Sleep(time.Second)
}

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

func sayGoodbye() {
    fmt.Println("Goodbye, world!")
}

Enter fullscreen mode Exit fullscreen mode

In this example, we're creating two goroutines that will print "Hello, world!" and "Goodbye, world!" respectively. The time.Sleep(time.Second) call is used to wait for the goroutines to finish executing before the program exits.

When a goroutine is created, it's scheduled to run on one of the available logical processors. The Go runtime manages a pool of logical processors and assigns goroutines to them based on a number of factors, including their priority, I/O blocking status, and CPU usage. This allows the Go runtime to handle thousands of goroutines at once without significant performance overhead.

Goroutines communicate with each other using channels. A channel is essentially a way in golang that allows data to be passed between goroutines in a thread-safe manner. Here's an example:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)

    go sendNumbers(ch)
    go receiveNumbers(ch)

    time.Sleep(time.Second)
}

func sendNumbers(ch chan<- int) {
    for i := 1; i <= 10; i++ {
        ch <- i
    }
    close(ch)
}

func receiveNumbers(ch <-chan int) {
    for num := range ch {
        fmt.Println(num)
    }
}

Enter fullscreen mode Exit fullscreen mode

In this example, we're creating a channel that can only be used to send integers (ch chan<- int) and another channel that can only be used to receive integers (ch <-chan int). We're then creating two goroutines: one to send the numbers 1 to 10 to the channel, and another to receive the numbers and print them out.

The close(ch) call is used to indicate that no more values will be sent on the channel. This is important, as it allows the receiving goroutine to know when it should stop waiting for new values.

Why Goroutines are Powerful

Goroutines are a powerful tool for concurrent programming because they make it easy to write highly concurrent and efficient code. Goroutines are lightweight and can be created and destroyed quickly and easily, allowing for dynamic concurrency that can adapt to changing workloads. The Go runtime handles the scheduling of goroutines, which allows for highly efficient and scalable concurrent programs.

Channels are also a powerful feature of Go, as they provide a safe and efficient way to communicate between goroutines. Channels allow goroutines to send and receive data without the need for locks or other synchronization primitives. This makes it easy to write highly concurrent programs that are free from data races and other synchronization issues.

Size of a Goroutine

Goroutines in Go are very lightweight and have a small initial stack size of only a few kilobytes (typically 2KB or 4KB, depending on the platform). However, the actual size of a goroutine can grow dynamically as needed when it performs function calls or allocates memory on the heap.

The Go runtime uses a technique called "stack growth" to dynamically increase the stack size of a goroutine when needed. When a goroutine's stack is almost full, the Go runtime will allocate a new stack segment and copy the contents of the old stack to the new stack. This process can occur multiple times as needed, allowing a goroutine to grow its stack as needed to handle larger and more complex tasks.

This dynamic stack growth mechanism allows Go to handle a large number of goroutines efficiently, as each goroutine only uses as much memory as it needs, and the stack size can grow as needed to handle more complex tasks. Additionally, this mechanism also helps prevent stack overflow errors that can occur in other programming languages when a function call chain becomes too deep.

Conclusion

Goroutines are a unique feature of the Go programming language that make it easy to write highly concurrent and efficient programs. Goroutines are lightweight and can be created and destroyed quickly and easily, and the Go runtime handles the scheduling of goroutines, which allows for highly efficient and scalable concurrent programs. Channels provide a safe and efficient way to communicate between goroutines, making it easy to write highly concurrent programs that are free from data races and other

Top comments (0)