并发网络请求
使用协程进行并发网络请求是Go语言中常见的应用之一。在传统的编程语言中,通常使用多线程来实现并发网络请求,但是多线程的管理和调度通常比较繁琐复杂。而在Go语言中,协程的创建和调度非常简单,使得实现并发网络请求变得非常容易。 通过使用协程,我们可以同时发起多个网络请求,并等待它们完成。这样可以大大提高网络请求的并发度,从而加快整体的执行速度。下面是一个示例代码:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
urls := []string{
"http://www.example.com",
"http://www.google.com",
"http://www.github.com",
}
for _, url := range urls {
go func(url string) {
resp, err := http.Get(url)
if err != nil {
fmt.Printf("Error fetching %s: %v\n", url, err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Error reading body of %s: %v\n", url, err)
return
}
fmt.Printf("Size of %s: %d\n", url, len(body))
}(url)
}
// 等待所有协程完成
time.Sleep(time.Second)
}
并发任务处理
除了处理网络请求外,协程还可以用于处理各种并发的任务。例如,在一个Web服务器中,我们可能需要同时处理多个客户端的请求。通过使用协程,我们可以将每个客户端的请求分配给一个独立的协程来处理,从而提高服务器的并发能力。 例如,下面是一个简单的Web服务器示例:
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal(err)
}
}
任务并发调度
除了并发处理任务外,协程还可以用于调度任务的执行顺序。通过使用通道(channel),我们可以在协程之间进行数据传递和同步,从而实现精细的任务调度。 例如,下面是一个简单的示例代码,演示了如何使用通道和协程进行任务调度:
package main
import (
"fmt"
"time"
)
func worker(id int, tasks <-chan int, results chan<- int) {
for task := range tasks {
fmt.Printf("Worker %d started task %d\n", id, task)
time.Sleep(time.Second)
fmt.Printf("Worker %d finished task %d\n", id, task)
results <- task * 2
}
}
func main() {
tasks := make(chan int, 10)
results := make(chan int, 10)
for i := 0; i < 3; i++ {
go worker(i, tasks, results)
}
for i := 0; i < 10; i++ {
tasks <- i
}
close(tasks)
for i := 0; i < 10; i++ {
result := <-results
fmt.Printf("Result %d\n", result)
}
}