package main import ( "context" "fmt" "sync" "sync/atomic" "time" ) // 5.1 Goroutine 基础 func say(s string) { for i := 0; i < 3; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func goroutineBasic() { fmt.Println("=== Goroutine 基础 ===") go say("world") say("hello") time.Sleep(500 * time.Millisecond) } // 5.2 GMP 模型演示 func gmpDemo() { fmt.Println("\n=== GMP 模型 ===") fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Printf("NumCPU: %d\n", runtime.NumCPU()) fmt.Printf("NumGoroutine: %d\n", runtime.NumGoroutine()) } // 5.3 Channel 基础 func channelBasic() { fmt.Println("\n=== Channel 基础 ===") // 无缓冲 Channel ch := make(chan int) go func() { ch <- 42 }() val := <-ch fmt.Println("无缓冲 Channel:", val) // 有缓冲 Channel bufferedCh := make(chan int, 2) bufferedCh <- 1 bufferedCh <- 2 fmt.Println("有缓冲 Channel:", <-bufferedCh, <-bufferedCh) } // 5.3 Channel 关闭与遍历 func channelClose() { fmt.Println("\n=== Channel 关闭与遍历 ===") ch := make(chan int) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }() for val := range ch { fmt.Print(val, " ") } fmt.Println() // 检查关闭 if _, ok := <-ch; !ok { fmt.Println("Channel 已关闭") } } // 5.3 工作池 func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Printf("Worker %d 处理 %d\n", id, j) time.Sleep(100 * time.Millisecond) results <- j * 2 } } func workerPoolDemo() { fmt.Println("\n=== 工作池 ===") jobs := make(chan int, 10) results := make(chan int, 10) for w := 1; w <= 3; w++ { go worker(w, jobs, results) } for j := 1; j <= 5; j++ { jobs <- j } close(jobs) for r := 1; r <= 5; r++ { <-results } fmt.Println("工作池完成") } // 5.3 Select func selectDemo() { fmt.Println("\n=== Select ===") ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(500 * time.Millisecond) ch1 <- "来自 ch1" }() go func() { time.Sleep(300 * time.Millisecond) ch2 <- "来自 ch2" }() for i := 0; i < 2; i++ { select { case msg1 := <-ch1: fmt.Println(msg1) case msg2 := <-ch2: fmt.Println(msg2) case <-time.After(1 * time.Second): fmt.Println("超时") return } } } // 5.4 WaitGroup func waitGroupDemo() { fmt.Println("\n=== WaitGroup ===") var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() fmt.Printf("Worker %d 开始\n", id) time.Sleep(200 * time.Millisecond) fmt.Printf("Worker %d 完成\n", id) }(i) } wg.Wait() fmt.Println("所有任务完成") } // 5.4 Mutex func mutexDemo() { fmt.Println("\n=== Mutex ===") var mu sync.Mutex var count int for i := 0; i < 1000; i++ { go func() { mu.Lock() count++ mu.Unlock() }() } time.Sleep(1 * time.Second) fmt.Println("Count:", count) } // 5.4 RWMutex func rwMutexDemo() { fmt.Println("\n=== RWMutex ===") var mu sync.RWMutex var data = make(map[string]int) var wg sync.WaitGroup // 读操作 for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() mu.RLock() _ = data["key"] mu.RUnlock() }() } // 写操作 for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() mu.Lock() data["key"]++ mu.Unlock() }() } wg.Wait() fmt.Println("Data:", data) } // 5.4 Once func onceDemo() { fmt.Println("\n=== Once ===") var once sync.Once setup := func() { fmt.Println("初始化一次") } for i := 0; i < 5; i++ { go func() { once.Do(setup) }() } time.Sleep(500 * time.Millisecond) } // 5.5 Atomic func atomicDemo() { fmt.Println("\n=== Atomic ===") var count int64 for i := 0; i < 1000; i++ { go func() { atomic.AddInt64(&count, 1) }() } time.Sleep(1 * time.Second) fmt.Println("Atomic Count:", atomic.LoadInt64(&count)) } // 5.6 Context func contextDemo() { fmt.Println("\n=== Context ===") ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() go func() { select { case <-time.After(1 * time.Second): fmt.Println("任务完成") case <-ctx.Done(): fmt.Println("任务取消:", ctx.Err()) } }() time.Sleep(1 * time.Second) } // 5.8 管道 func pipelineDemo() { fmt.Println("\n=== 管道 ===") // 生成 gen := func(nums ...int) <-chan int { out := make(chan int) go func() { for _, n := range nums { out <- n } close(out) }() return out } // 平方 sq := func(in <-chan int) <-chan int { out := make(chan int) go func() { for n := range in { out <- n * n } close(out) }() return out } c := gen(1, 2, 3) c = sq(c) for n := range c { fmt.Println(n) } } // 5.9 并发爬虫 type Crawler struct { visited map[string]bool mu sync.Mutex wg sync.WaitGroup limit chan struct{} } func (c *Crawler) crawl(url string, depth int) { if depth <= 0 { return } c.limit <- struct{}{} defer func() { <-c.limit }() defer c.wg.Done() c.mu.Lock() if c.visited[url] { c.mu.Unlock() return } c.visited[url] = true c.mu.Unlock() fmt.Println("抓取:", url) // 模拟子链接 links := []string{url + "/1", url + "/2"} for _, link := range links { c.wg.Add(1) go c.crawl(link, depth-1) } } func crawlerDemo() { fmt.Println("\n=== 并发爬虫 ===") crawler := &Crawler{ visited: make(map[string]bool), limit: make(chan struct{}, 5), } crawler.wg.Add(1) go crawler.crawl("http://example.com", 2) crawler.wg.Wait() fmt.Println("爬虫完成") } // 5.10 竞态检测示例(需配合 -race 运行) func raceDemo() { fmt.Println("\n=== 竞态检测示例 ===") var count int for i := 0; i < 100; i++ { go func() { count++ // 竞态! }() } time.Sleep(1 * time.Second) fmt.Println("Count:", count) } func main() { goroutineBasic() gmpDemo() channelBasic() channelClose() workerPoolDemo() selectDemo() waitGroupDemo() mutexDemo() rwMutexDemo() onceDemo() atomicDemo() contextDemo() pipelineDemo() crawlerDemo() raceDemo() }