ZBLOG

package main import ( "fmt" "sync" "time" ) func main() { chaS := make([]chan struct{}, 10) var global = 1 wg := sync.WaitGroup{} for i := 0; i < 10; i++ {

你遇到死锁的原因是因为你的代码在使用通道(chan)时没有正确初始化和使用这些通道。具体来说,以下几点可能导致死锁:

  1. 未初始化的通道chaS[i] 在你进行 <-chaS[i] 操作之前没有被初始化,因此会导致在等待接收的时候出现阻塞,从而导致死锁。

  2. 同步问题:每次你尝试从 chaS[(i+1)/10] <- struct{}{} 发送一个信号,只有当 i 的值为 9 时, (i+1)/10 会等于 1,否则会产生数组越界错误。这里应该是 chaS[(i+1)%10] 或者其他逻辑,以确保索引始终在有效范围内。

  3. 循环中的 goroutine 调用顺序:你的主线程调用了所有的 goroutine,但是 goroutine 内部的处理并不会立即触发。这意味着如果第一个 go func(i int) 没有完成,则下一个协程无法启动,形成一种等待条件。

下面是修复后的代码示例,可以帮助您理解如何避免这种情况:

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	chaS := make([]chan struct{}, 10)
	for i := range chaS {
		chaS[i] = make(chan struct{}) // 初始化每个通道
	}

	var global = 1
	wg := sync.WaitGroup{}

	go func() { // 启动第一个 goroutine
		wg.Add(1)
		defer wg.Done()
		
		fmt.Println(global)
		time.Sleep(time.Second)
		global++
		
		for j := 0; j < len(chaS)-1; j++ {
			chaS[j] <- struct{}{} // 通知下一个 goroutine 启动
			if j == len(chaS)-2 { // 如果已经到达最后一个,关闭最后的通道以防止死锁
				close(chaS[j])
			}
			time.Sleep(time.Millisecond) // 增加一些延迟以确保顺序执行可见
		}
	}()

	for i := 0; i < len(chaS); i++ {
		if i > 0 { 
			<-chaS[i-1] // 等待前一个 goroutine 完成后再继续执行
        }
        go func(i int) {
            defer wg.Done()
            fmt.Println(global)
            time.Sleep(time.Second)
            global++
        }(i)
    }

	wg.Wait()
}

上述代码通过确保每个 channel 都已正确初始化并处理了 goroutines 的启动顺序,以避免任何潜在的死锁情况。请根据实际需求调整代码结构和逻辑。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?