Update tech_docs/go_getting_started.md
This commit is contained in:
@@ -1,3 +1,209 @@
|
|||||||
|
Certainly! Here's a concise guide to goroutines and channels in Go, covering all major points.
|
||||||
|
|
||||||
|
## Goroutines
|
||||||
|
|
||||||
|
Goroutines are lightweight threads managed by the Go runtime. They allow you to perform concurrent tasks without the overhead of traditional threads.
|
||||||
|
|
||||||
|
### Key Points
|
||||||
|
|
||||||
|
1. **Lightweight**: Goroutines are much lighter than OS threads, allowing you to run thousands of them simultaneously.
|
||||||
|
2. **Easy to Use**: Creating a goroutine is as simple as adding the `go` keyword before a function call.
|
||||||
|
3. **Automatic Scheduling**: The Go runtime schedules goroutines, making efficient use of system resources.
|
||||||
|
|
||||||
|
### Creating Goroutines
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func say(s string) {
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
go say("world") // This runs concurrently
|
||||||
|
say("hello")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Waiting for Goroutines
|
||||||
|
|
||||||
|
Using `sync.WaitGroup` to wait for goroutines to finish:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func worker(id int, wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
fmt.Printf("Worker %d starting\n", id)
|
||||||
|
// Simulate work
|
||||||
|
fmt.Printf("Worker %d done\n", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
for i := 1; i <= 5; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go worker(i, &wg)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Avoid Blocking**: Long-running or blocking operations should not be in the main goroutine.
|
||||||
|
2. **Error Handling**: Properly handle errors within goroutines.
|
||||||
|
3. **Resource Cleanup**: Ensure resources are properly cleaned up using `defer`.
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
Channels provide a way for goroutines to communicate with each other and synchronize their execution.
|
||||||
|
|
||||||
|
### Key Points
|
||||||
|
|
||||||
|
1. **Typed**: Channels are typed conduits through which you can send and receive values of a specific type.
|
||||||
|
2. **Safe**: Channels provide a safe way to share data between goroutines without explicit locks.
|
||||||
|
3. **Directional**: Channels can be directional, meaning they can be restricted to send-only or receive-only.
|
||||||
|
|
||||||
|
### Creating Channels
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
messages := make(chan string)
|
||||||
|
|
||||||
|
go func() { messages <- "ping" }()
|
||||||
|
|
||||||
|
msg := <-messages
|
||||||
|
fmt.Println(msg)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buffered Channels
|
||||||
|
|
||||||
|
Buffered channels allow you to specify the capacity of the channel.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
messages := make(chan string, 2)
|
||||||
|
|
||||||
|
messages <- "buffered"
|
||||||
|
messages <- "channel"
|
||||||
|
|
||||||
|
fmt.Println(<-messages)
|
||||||
|
fmt.Println(<-messages)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Channel Directions
|
||||||
|
|
||||||
|
You can specify if a channel is send-only or receive-only:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func sendMessage(ch chan<- string, msg string) {
|
||||||
|
ch <- msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func receiveMessage(ch <-chan string) {
|
||||||
|
fmt.Println(<-ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch := make(chan string)
|
||||||
|
go sendMessage(ch, "hello")
|
||||||
|
receiveMessage(ch)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Select Statement
|
||||||
|
|
||||||
|
The `select` statement lets a goroutine wait on multiple communication operations.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch1 := make(chan string)
|
||||||
|
ch2 := make(chan string)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ch1 <- "message from ch1"
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ch2 <- "message from ch2"
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case msg1 := <-ch1:
|
||||||
|
fmt.Println(msg1)
|
||||||
|
case msg2 := <-ch2:
|
||||||
|
fmt.Println(msg2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Closing Channels
|
||||||
|
|
||||||
|
Closing a channel indicates that no more values will be sent on it.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ch := make(chan int)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
ch <- i
|
||||||
|
}
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
for v := range ch {
|
||||||
|
fmt.Println(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Avoid Deadlocks**: Ensure that channels are properly managed to avoid deadlocks.
|
||||||
|
2. **Channel Capacity**: Use buffered channels when you need to decouple the timing between sending and receiving.
|
||||||
|
3. **Closing Channels**: Close channels to signal completion of communication.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# Go (Golang) Comprehensive Guide
|
# Go (Golang) Comprehensive Guide
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|||||||
Reference in New Issue
Block a user