您的位置:首页 > 汽车 > 新车 > 网站设置flash_展示商品的网站怎么做_上海职业技能培训机构一览表_培训报名

网站设置flash_展示商品的网站怎么做_上海职业技能培训机构一览表_培训报名

2024/12/26 10:25:09 来源:https://blog.csdn.net/YiGeiGiaoGiao/article/details/144368761  浏览:    关键词:网站设置flash_展示商品的网站怎么做_上海职业技能培训机构一览表_培训报名
网站设置flash_展示商品的网站怎么做_上海职业技能培训机构一览表_培训报名

注意1:使用指针

  1. 当把WaitGroup作为参数传递给函数时,如果传递的是变量本身(值传递),会发生复制。在 Go 语言中,这种复制可能会导致意外的行为。因为每个WaitGroup副本都有自己独立的计数器
  2. 下面的代码如果worker(wg)这里没有传递指针,那么worker函数接收到的是wg的一个副本。worker函数中的Done操作是在副本上进行的,而main函数中的Wait操作是在原始的wg上进行的。这样就会导致main函数中的Wait可能永远阻塞,因为原始wg的计数器没有被正确地减少。
   package mainimport ("fmt""sync")func worker(wg *sync.WaitGroup) {defer wg.Done()fmt.Println("Worker is running")}func main() {var wg sync.WaitGroupwg.Add(1)// 传递指针worker(&wg)wg.Wait()}

注意2:正确的计数器操作顺序

这一点十分容易出现很隐蔽的错误

  1. Add方法调用时机:必须在goroutine 启动之前调用Add方法来增加计数器的值。如果在goroutine已经启动之后再调用Add,可能会导致Wait方法提前返回,因为计数器没有正确反映正在运行的goroutine的数量。把握住:Add()与Wait()保证在同一个函数中

           var wg sync.WaitGroup// 错误示例,在goroutine启动后才调用Addgo func() {wg.Add(1)fmt.Println("Goroutine is running")wg.Done()}()wg.Wait()
    

    下面是一个更加隐蔽的例子:

    func TestDistribute(t *testing.T) {numOfTask := 5resChan := make(chan int, numOfTask)addTaskChan := make(chan *AddTask, numOfTask)var wg sync.WaitGroupgo initTask(addTaskChan, numOfTask, 11, resChan)go DistributeTasks(addTaskChan, numOfTask, &wg)  // 没有在开启协程之前Add,开启之后在内部Add,就容易出问题res := 0wg.Wait()-----------------------------------
    func DistributeTasks(taskChan <-chan *AddTask, numOfTasks int, wg *sync.WaitGroup) {for task := range taskChan {wg.Add(1) // 在下面这个协程Add,只能保证在这个位置进行wg.Wait(),外面的函数无法保证go func(t *AddTask) {defer wg.Done()t.Do()}(task) // 注意要当作参数传入,而不是直接在 开启的协程 内部调用task,// wg.Wait() 在这个地方有效,外部就不行了}
    }
    

注意3:var wg sync.WaitGroup与wg := sync.WaitGroup{}区别

  1. var wg sync.WaitGroup
    这种写法声明了一个 sync.WaitGroup 类型的变量 wg,但是它没有进行初始化,默认情况下是零值初始化。Go 中的零值初始化意味着 wg 会被自动初始化为 sync.WaitGroup{},即一个空的 WaitGroup,你可以直接使用它。
  2. wg := sync.WaitGroup{}
    这种写法是对 sync.WaitGroup 的显式初始化,并且是局部变量的声明方式。 var wg sync.WaitGroup 的效果,初始化了一个新的空的 WaitGroup 变量。
  3. 使用 new(sync.WaitGroup) ,注意这里返回的是一个指针,这个时候回到第一点,传递wg的时候可以不需要使用 &wg取地址操作

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com