Files
labmem d375463de5 refactor(go)!: 分离练习区与独立项目区
- 将现有练习及 module 文件迁移至 go/practice,保持代码和依赖不变
- 新增 go/projects 项目区说明,更新目录约定与开发命令

BREAKING CHANGE: Go 练习命令需改在 go/practice 目录下执行
2026-10-15 22:26:57 +08:00

51 lines
1.2 KiB
Go

package main
import (
"context"
"fmt"
"math/rand"
"net/http"
_ "net/http/pprof"
"time"
)
// 来自文章 https://www.cnblogs.com/hwnd/p/20682814
func simulateRequest() {
timeout := 500 * time.Millisecond
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout))
defer cancel()
resultCh := make(chan string) // 无缓冲!
// 启动 worker goroutine 处理"请求"
go func() {
time.Sleep(time.Duration(rand.Intn(500)+300) * time.Millisecond)
select {
case <-time.After(timeout):
fmt.Println("worker 超时,放弃处理")
case <-ctx.Done():
case resultCh <- fmt.Sprintf("处理完成,耗时 %dms", rand.Intn(500)+300):
}
}()
// TODO: 模拟请求取消或超时的情况(比如 500ms 后调用方不再关心结果)
// 如果 worker 还没完成,它就 leak 了
select {
case resultCh := <-resultCh:
fmt.Println(resultCh)
case <-ctx.Done():
fmt.Println("请求方取消了请求")
}
}
func main() {
for i := 0; i < 5; i++ {
simulateRequest()
fmt.Printf("第 %d 个请求处理完毕\n\n", i+1)
time.Sleep(200 * time.Millisecond)
}
fmt.Println("所有请求处理完毕")
// 运行后观察:goroutine 数量只增不减
http.ListenAndServe(":6060", nil)
}