ZBLOG

package main import ( "fmt" "sync" ) func main() { chanT := make(chan int) wg := sync.WaitGroup{} go func() { wg.Add(1) defer wg.Done() for i := 0; i < 100; i++ { chanT

在你提供的 Go 代码中,程序会出现死锁(或“阻塞”)的问题。让我们逐步分析一下这个代码:

  1. 创建通道和 WaitGroup

    chanT := make(chan int)
    wg := sync.WaitGroup{}
    
  2. 启动一个 goroutine 来发送数据

    go func() {
       wg.Add(1)
       defer wg.Done()
       for i := 0; i < 100; i++ {
           chanT <- i
       }
    }()
    

    在这个 goroutine 中,你使用 chanT 通道向其发送了 100 个整数。

  3. 接收数据

    for task := range chanT {
       fmt.Println(task)
    }
    close(chanT)
    wg.Wait()
    

在这里,你有两个主要问题:

问题一:未关闭通道

  • 在主函数中,你尝试从 chanT 通道中读取数据,但你没有正确地关闭通道。由于没有关闭通道,for range 循环将会一直等待,直到通道被关闭,因此导致了死锁。

正确的做法:

为了避免死锁并确保正常运行,可以将 close(chanT) 移到 goroutine 完成后,并且在 wg.Wait() 后再调用它。以下是修复后的代码示例:

package main

import (
	"fmt"
	"sync"
)

func main() {
	chanT := make(chan int)
	wg := sync.WaitGroup{}
	
	go func() {
		wg.Add(1)
		defer wg.Done()
		for i := 0; i < 100; i++ {
			chanT <- i
		}
	}()
	
	go func() {
		wg.Wait() // 等待发送 goroutine 完成后关闭通道
		close(chanT) // 一旦所有任务完成,关闭通道
	}()
	
	for task := range chanT {
		fmt.Println(task)
	}
}

总结

  • 使用 sync.WaitGroup 的好处是可以确保在执行完所有任务后才关闭通道,这样可以避免因提前关闭通道而导致的 panic。
  • 确保合理安排并发任务的生命周期,以有效利用 Go 的并发特性。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20256

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?