Go中并发编程利用goroutine(轻量级线程)和channel(通信管道)实现。goroutine通过go关键字创建,非常轻量,可创建大量goroutine,且不会影响性能。channel用于goroutine间通信,是类型化的管道。本例展示了并发爬虫的应用,使用goroutine并行爬取URL,提高效率。
Go 核心技术解析:并发编程
Go 中的并发模型基于 goroutine(轻量级线程)和 channel(通信管道)的概念。通过充分利用这些特性,开发者可以构建高并发、高性能的应用程序。
Goroutine
Goroutine 是 Go 中的轻量级线程,由关键字 go
创建。它们在协程调度器上运行,与传统线程不同,goroutine 非常轻量,可以创建数千个而不会对性能造成重大影响。以下代码展示了如何创建和使用 goroutine:
package main import ( "fmt" "runtime" ) func main() { fmt.Printf("Number of goroutines: %d\n", runtime.NumGoroutine()) // 当前正在运行的 goroutine 数量 // 创建一个 goroutine go func() { fmt.Println("Hello from a goroutine!") }() fmt.Printf("Number of goroutines: %d\n", runtime.NumGoroutine()) // 当前正在运行的 goroutine 数量 }
Channel
Channel 是用于 goroutine 之间通信的管道。它们是类型化的,这意味着它们只能传递特定类型的值。以下代码展示了如何创建和使用 channel:
package main import ( "fmt" ) func main() { // 创建一个 int 类型的 channel c := make(chan int) // 向 channel 发送值 go func() { c <- 42 }() // 从 channel 接收值 v := <-c fmt.Println(v) // 输出:42 }
实战案例:并发爬虫
以下是一个使用 goroutine 和 channel 构建并发爬虫的简化示例:
package main import ( "fmt" "net/http" "sync" ) var wg sync.WaitGroup func main() { // 要爬取的 URL 列表 urls := []string{ "https://example.com", "https://example2.com", "https://example3.com", } // 创建 channel 来接收每个 URL 的响应 results := make(chan string) // 为每个 URL 创建一个 goroutine for _, url := range urls { wg.Add(1) go func(url string) { resp, err := http.Get(url) if err != nil { fmt.Printf("Error fetching %s: %v\n", url, err) } else if resp.StatusCode == 200 { results <- url } wg.Done() }(url) } // 从 channel 中获取响应 go func() { for url := range results { fmt.Println(url) } }() // 等待所有 goroutine 完成 wg.Wait() }
通过使用 goroutine 和 channel,此爬虫可以并发爬取多个 URL,从而提高了效率。
以上是Go语言核心技术解析的详细内容。更多信息请关注PHP中文网其他相关文章!