案例一:构建一个简单的Web服务器
在Go语言中,创建一个简单的Web服务器是一件非常简单的事情。以下是一个基础的HTTP服务器的实现,它能够处理GET请求并返回一个简单的HTML页面。
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h1>Welcome to the Go Web Server!</h1>")
})
fmt.Println("Starting server at port 8080...")
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Println("Error starting server:", err)
}
}
在这个案例中,我们使用了http.HandleFunc来注册一个处理函数,它会响应所有对根路径/的GET请求。fmt.Fprintf用于向客户端发送一个简单的HTML页面。
案例二:使用goroutine处理并发请求
Go语言的一个核心特性是goroutine,它是轻量级的线程,可以用来处理并发任务。以下是一个使用goroutine来处理并发请求的例子。
package main
import (
"fmt"
"net/http"
"time"
)
func handleRequest(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second) // 模拟耗时操作
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handleRequest)
fmt.Println("Starting server at port 8080...")
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Println("Error starting server:", err)
}
}
在这个例子中,我们使用time.Sleep来模拟一个耗时的操作。即使服务器同时收到多个请求,每个请求也会在goroutine中独立执行,因此服务器可以同时处理多个请求。
技巧分享:结构化并发处理
在Go语言中,处理并发时,可以使用channel来实现goroutine之间的通信。以下是一个使用channel来同步goroutine的例子。
package main
import (
"fmt"
"net/http"
"sync"
)
func worker(id int, jobs <-chan string, done chan<- bool) {
for j := range jobs {
fmt.Printf("worker %d started job %s\n", id, j)
// 模拟工作
time.Sleep(time.Second)
fmt.Printf("worker %d finished job %s\n", id, j)
}
done <- true
}
func main() {
jobs := make(chan string)
done := make(chan bool)
// 启动3个worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, done)
}
// 发送10个任务到jobs channel
for j := 1; j <= 10; j++ {
jobs <- fmt.Sprintf("job %d", j)
}
close(jobs) // 所有任务都发送完毕,关闭jobs channel
// 等待所有worker完成
for w := 1; w <= 3; w++ {
<-done
}
fmt.Println("All jobs finished.")
}
在这个例子中,我们创建了三个goroutine来处理任务。每个worker从jobs channel接收任务,并将完成信号发送到done channel。主goroutine等待所有worker完成工作。
总结
Go语言以其并发处理能力和简洁的语法而闻名。通过上述案例,我们可以看到如何使用Go语言创建Web服务器、处理并发请求以及使用goroutine和channel进行结构化并发处理。掌握这些技巧对于编写高效、可扩展的Go程序至关重要。
