Goroutine简介定义:Goroutine是一种轻量级线程,由Go运行时管理。它比操作系统级别的线程更轻量,创建成本低,切换速度快。创建方式:通过go关键字启动一个新goroutine。gofunc(){fmt.Println("Hellofromgoroutine"
go func() {
fmt.Println("Hello from goroutine")
}()
ch := make(chan int) // 声明一个整型channel
ch <- 42 // 向channel发送数据
x := <-ch // 从channel接收数据
fmt.Println(x) // 输出: 42
生产者消费者模型:通过channel连接生产者和消费者。
func producer(ch chan<- int) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}
func consumer(ch <-chan int) {
for n := range ch {
fmt.Println(n)
}
}
func main() {
ch := make(chan int)
go producer(ch)
consumer(ch)
}
工作池:通过固定数量的goroutine处理任务队列。
type WorkerPool struct {
jobs chan int
done chan bool
count int
}
func NewWorkerPool(n int) *WorkerPool {
return &WorkerPool{
jobs: make(chan int, 100),
done: make(chan bool, n),
count: n,
}
}
func (p *WorkerPool) Start() {
for i := 0; i < p.count; i++ {
go func() {
for job := range p.jobs {
fmt.Println("Working on", job)
time.Sleep(time.Second)
}
p.done <- true
}()
}
}
func (p *WorkerPool) AddJob(jobs ...int) {
for _, job := range jobs {
p.jobs <- job
}
}
func (p *WorkerPool) Wait() {
for i := 0; i < p.count; i++ {
<-p.done
}
close(p.jobs)
}
func main() {
wp := NewWorkerPool(5)
wp.Start()
wp.AddJob(1, 2, 3, 4, 5)
wp.Wait()
}
使用context包可以方便地设置超时。
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
select {
case <-ctx.Done():
fmt.Println("Timed out")
case result := <-ch:
fmt.Println("Result:", result)
}
在并发程序中,错误处理尤为重要。
func doWork(ch chan<- error) {
defer func() {
if r := recover(); r != nil {
ch <- errors.New("panic occurred")
}
}()
// 可能引发panic的操作
fmt.Println(1 / 0)
}
func main() {
ch := make(chan error)
go doWork(ch)
if err := <-ch; err != nil {
log.Fatal(err)
}
}
假设我们需要开发一个简单的Web服务器,该服务器能够同时处理多个客户端请求,并且每个请求都可能触发一些耗时较长的操作(如数据库查询)。我们可以利用goroutine和channel来实现这一功能:
package main
import (
"fmt"
"log"
"net/http"
)
func handleRequest(w http.ResponseWriter, r *http.Request) {
// 模拟耗时操作
ch := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch <- "Hello, World!"
}()
// 等待结果返回
result := <-ch
fmt.Fprintln(w, result)
}
func main() {
http.HandleFunc("/", handleRequest)
log.Fatal(http.ListenAndServe(":8080", nil))... 如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!