【干货】Golang 并发编程:从基础到实践 Golang 是一种高效的编程语言,同时也是一种支持并发编程的语言。在 Golang 中,使用 goroutine、channel 和 select 等关键词可以很方便地进行并发编程。本文将从基础到实践,介绍 Golang 并发编程的相关知识点。 一、基础知识点 1. goroutine Goroutine 是 Golang 中的轻量级线程,可以在单个程序中并发执行多个任务。创建 Goroutine 的方式是在前面加上关键字 go,例如 go func() { ... }()。通过关键字 go 可以让函数在一个新的 Goroutine 中运行,同时不会阻塞当前 Goroutine。 2. channel Channel 是 Golang 中的通信机制,可以让 Goroutine 之间进行通信。Channel 可以用来同步 Goroutine 的执行,也可以用于传递数据。创建一个 channel 的方式是使用 make 函数,例如 ch := make(chan int)。 3. select Select 是 Golang 中的多路复用机制,可以同时监听多个 channel 的操作。当多个 channel 中有数据可读或可写时,select 会随机选择一个 channel 并执行相应的操作。使用 select 可以避免 Goroutine 阻塞等待某个 channel 的数据。 二、实践应用 1. 生产者-消费者模型 生产者-消费者模型是一种常见的并发编程模型。在该模型中,有一个生产者 Goroutine 负责生成数据并将数据发送到一个 channel 中,而多个消费者 Goroutine 则从该 channel 中接收数据并进行处理。下面是一个简单的生产者-消费者模型的实现: ```go func producer(ch chan int) { for i := 0; i < 10; i++ { ch <- i } close(ch) } func consumer(ch chan int, wg *sync.WaitGroup) { for i := range ch { fmt.Println("Received:", i) time.Sleep(100 * time.Millisecond) } wg.Done() } func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go producer(ch) go consumer(ch, &wg) go consumer(ch, &wg) wg.Wait() } ``` 2. 并发下载器 并发下载器是一种常见的多线程应用。在该应用中,有多个 Goroutine 同时下载指定链接的文件,并将下载结果保存到本地。下面是一个简单的并发下载器的实现: ```go func download(url string, filename string, ch chan bool) { res, err := http.Get(url) if err != nil { log.Fatal(err) } defer res.Body.Close() file, err := os.Create(filename) if err != nil { log.Fatal(err) } defer file.Close() io.Copy(file, res.Body) ch <- true } func main() { urls := []string{"http://example.com/file1", "http://example.com/file2", "http://example.com/file3"} ch := make(chan bool, len(urls)) for _, url := range urls { filename := url[strings.LastIndex(url, "/")+1:] go download(url, filename, ch) } for i := 0; i < len(urls); i++ { <-ch } fmt.Println("All files downloaded") } ``` 在以上代码中,我们使用了带有缓冲的 channel,可以让下载 Goroutine 先将下载结果发送到 channel 中,然后通过主 Goroutine 读取 channel 中的数据,以确保所有文件都下载完成后再输出下载结果。 三、总结 本文通过介绍 Goroutine、channel 和 select 等关键词,以及生产者-消费者模型和并发下载器的实现方式,希望能够帮助读者更好地理解和应用 Golang 的并发编程。同时,需要注意 Goroutine 和 channel 的使用,以确保程序的正确性和稳定性。