Goroutine 是 Go 语言中的轻量级线程,可以在同一个进程中同时运行成百上千个 Goroutine。与操作系统线程相比,Goroutine 的创建和销毁的代价非常低,因此可以轻松地创建大量的 Goroutine,以实现高并发的处理能力。
一个线程里可以同时执行多个协程,Go
可以同时创建上万级别的协程,也是Go
支持高并发原因之一。
Goroutine 的创建非常简单,只需要在函数调用前添加关键字 go
即可。例如:
func main() {
go func() {
// do something
}()
}
创建了一个匿名函数并在其前面添加了关键字 go
,这将使该函数在一个新的 Goroutine 中运行。
Channel 是 Go 语言中用于 Goroutine 之间通信的机制。通过 Channel,Goroutine 可以相互发送和接收数据,从而实现协作处理任务的能力。
创建一个 Channel 非常简单,只需要使用内置函数 make
,并指定 Channel 的类型即可。例如:
ch := make(chan int)
创建了一个类型为 int
的 Channel。
发送数据到 Channel 中使用 <-
操作符,接收数据则使用 <-
操作符。例如:
ch := make(chan int)
go func() {
ch <- 1
}()
num := <-ch
创建了一个 Goroutine,向 Channel 中发送了一个整数 1
。然后在主 Goroutine 中,我们从 Channel 中接收了这个整数。
Select 是 Go 语言中用于处理多个 Channel 的机制。通过 Select,可以在多个 Channel 上等待数据,并在数据到达时进行处理。
使用 Select 非常简单,只需要在多个 Channel 上使用 <-
操作符,并将它们包含在一个 Select 语句中即可。例如:
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
ch1 <- 1
}()
go func() {
ch2 <- 2
}()
select {
case num := <-ch1:
fmt.Println("Received from ch1:", num)
case num := <-ch2:
fmt.Println("Received from ch2:", num)
}
创建了两个 Goroutine,分别向两个 Channel 中发送了整数 1
和 2
。然后在主 Goroutine 中,我们使用 Select 等待这两个 Channel 中的数据,并在数据到达时进行处理。
Mutex 是 Go 语言中用于实现互斥锁的机制。通过 Mutex,可以保证同一时刻只有一个 Goroutine 可以访问共享资源,从而避免并发访问导致的数据竞争问题。Mutex
是一种互斥锁。
使用 Mutex 非常简单,只需要在需要保护的代码块前后分别调用 Lock
和 Unlock
方法即可。例如:
var mu sync.Mutex
func main() {
mu.Lock()
defer mu.Unlock()
// do something
}
创建了一个名为 mu
的 Mutex,并在需要保护的代码块前后分别调用了 Lock
和 Unlock
方法。
WaitGroup 是 Go 语言中用于等待一组 Goroutine 完成的机制。通过 WaitGroup,可以等待一组 Goroutine 完成后再执行下一步操作。
使用 WaitGroup 非常简单,只需要在每个 Goroutine 开始时调用 Add
方法,在 Goroutine 结束时调用 Done
方法,然后在主 Goroutine 中调用 Wait
方法等待所有 Goroutine 完成即可。例如:
var wg sync.WaitGroup
func main() {
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
// do something
}(i)
}
wg.Wait()
}
创建了 10 个 Goroutine,并使用 WaitGroup 等待它们全部完成。在每个 Goroutine 中,我们调用了 Done
方法以通知 WaitGroup 该 Goroutine 已完成。
通过 Goroutine、Channel、Select、Mutex 和 WaitGroup 这些机制,Go 语言提供了强大的并发编程能力,使其成为了处理高并发场景的首选语言之一。
在实际开发中,可以根据具体场景选择合适的机制,并结合使用,以实现高效、安全、可靠的并发编程。