Go 并发
Go 并发
Go是一种支持并发编程的语言。它使用了一种称为“轻量级线程”(goroutine)的概念,这些线程可以在单个进程内并发运行。
Goroutine
Goroutine是Go语言中的一种并发执行机制,它类似于线程,但是比线程更轻量级,开销更小。在Go中,我们可以创建很多个goroutine,它们可以并行执行,并互不影响。
Goroutine可以通过关键字go来创建:
go function_name()
当我们在程序中使用关键字go创建goroutine时,它会立刻启动一个新的goroutine来执行相应的函数。注意,创建goroutine是异步的,即主程序不会等待goroutine执行完毕才继续执行。
Channel
在Go语言中,goroutine之间的通信可以通过channel来实现。Channel是一种数据类型,可以在goroutine之间传递数据。
创建一个channel:
var ch chan int // ch是一个int类型的channel
向channel发送数据:
ch <- 123 // 向ch中发送123
从channel接收数据:
x := <- ch // 从ch中接收数据,并将其赋值给x
当向一个channel发送数据时,如果没有别的goroutine在从这个channel中接收数据,那么发送方会被阻塞,直到有其他的goroutine从这个channel中接收数据。同理,当从一个channel中接收数据时,如果没有别的goroutine在向这个channel中发送数据,那么接收方会被阻塞,直到有其他的goroutine向这个channel中发送数据。
Select
Select语句用于从多个channel中接收数据。它类似于switch语句,但是用于多路复用IO操作。
以下是Select语句的一般形式:
select {
case <-channel1:
// 从channel1接收到数据时执行的代码
case data := <-channel2:
// 从channel2接收到数据时执行的代码
default:
// 默认执行的代码,如果所有的channel都没有数据可接收时就会执行
}
当执行Select语句时,如果有多个channel都可以接收数据,那么会随机选择一个channel进行操作。如果没有任何一个channel可以接收数据,则Select语句会被阻塞,直到有一个channel可以接收数据。
Mutex
Mutex是一种互斥锁,用于保护共享数据的访问。在Go中,我们可以使用sync.Mutex类型的变量来创建一个Mutex对象。
当代码需要访问共享数据时,需要先获取这个Mutex对象的锁,然后访问共享数据。当访问完成后,需要释放这个Mutex对象的锁。
以下是Mutex对象的基本使用方法:
var mutex sync.Mutex // 创建一个Mutex对象
mutex.Lock() // 获取锁
// 访问共享数据的代码
mutex.Unlock() // 释放锁
WaitGroup
WaitGroup用于等待一组goroutine的执行完成。在WaitGroup中,我们可以使用Add()方法增加一个goroutine的计数器,使用Done()方法减少一个goroutine的计数器,使用Wait()方法来等待所有goroutine的计数器归零。
以下是WaitGroup的基本使用方法:
var wg sync.WaitGroup // 创建一个WaitGroup对象
wg.Add(1) // 为一个goroutine的计数器 +1
go func() {
// goroutine的代码
wg.Done() // 为一个goroutine的计数器 -1
}()
wg.Wait() // 等待所有goroutine的计数器归零
Conclusion
Go语言通过Goroutine、Channel、Select、Mutex、WaitGroup等机制支持并发编程。它提供了简单易用的工具和语法来编写并发程序,大大提高了程序的性能和可维护性。