Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Introduction to Concurrency in Go Programming

What is Concurrency?

Concurrency is the ability of a program to make progress on multiple tasks simultaneously. It is a key concept in modern programming, as it allows for more efficient use of resources and better performance in multi-core systems. In Go, concurrency is achieved using goroutines and channels.

Goroutines

Goroutines are lightweight threads managed by the Go runtime. They are cheaper than traditional threads and can be created in large numbers. A goroutine is created using the go keyword followed by a function call. Here is a simple example:

package main

import (
    "fmt"
    "time"
)

func main() {
    go sayHello()
    time.Sleep(1 * time.Second)
}

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

In this example, the sayHello function is called as a goroutine. The main function sleeps for one second to allow the goroutine to complete its execution.

Channels

Channels are used to communicate between goroutines. They provide a way to send and receive values between goroutines safely. Channels are created using the make function. Here is an example:

package main

import "fmt"

func main() {
    messages := make(chan string)

    go func() {
        messages <- "Hello, Channel!"
    }()

    msg := <-messages
    fmt.Println(msg)
}

In this example, a channel of type string is created. A goroutine is used to send a message into the channel, and the main function receives the message and prints it.

Buffered Channels

Channels can be either unbuffered or buffered. Buffered channels have a capacity, and send operations will block only when the buffer is full. Here is an example:

package main

import "fmt"

func main() {
    messages := make(chan string, 2)

    messages <- "Hello"
    messages <- "World"

    fmt.Println(<-messages)
    fmt.Println(<-messages)
}

In this example, a buffered channel with a capacity of 2 is created. Two messages are sent into the channel without blocking, and then both messages are received and printed.

Select Statement

The select statement allows a goroutine to wait on multiple communication operations. It blocks until one of the cases can proceed. Here is an example:

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "One"
    }()

    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "Two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("Received", msg1)
        case msg2 := <-c2:
            fmt.Println("Received", msg2)
        }
    }
}

In this example, two goroutines send messages into two different channels after different sleep durations. The select statement waits for either channel to receive a message and prints it.

Conclusion

Concurrency is a powerful feature in Go that enables efficient execution of multiple tasks. By using goroutines and channels, Go provides a simple and effective way to handle concurrent programming. Understanding and mastering these concepts can significantly improve the performance and responsiveness of your applications.