Golang新手频繁遇到死锁错误问题求助

Golang新手频繁遇到死锁错误问题求助 Go Playground 链接

5 回复

我已链接一个格式正确的Go Playground版本

更多关于Golang新手频繁遇到死锁错误问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Go的数据竞争检测器。

go run -race main.go

我正在尝试从CSV文件中提取患者数据,然后解析数据以找出文件中哪些行包含不完整的患者信息。这是我第一次使用Golang,所以对这门语言还不太熟悉。如果需要关闭通道,请告诉我具体操作方法。感谢您的帮助。

func main() {
    fmt.Println("hello world")
}

你的通道是无缓冲的,因此当没有人从中接收消息时,你的goroutine会被阻塞。只需在单独的例程中启动消费函数:

		go consume(whichones, counter)

然后发送消息:

msgs <- record[value]

但是,你无法接收比发送数量更多的消息,因此请完全移除消费函数中的循环。

在您提供的代码中,死锁问题主要出现在 main 函数中,原因是没有正确处理 goroutine 的同步和通道的关闭。以下是详细分析和修复后的代码示例。

问题分析

  1. 通道未关闭ch 通道在 goroutine 中发送数据后未关闭,导致 main 函数中的 for 循环在读取完所有数据后无法退出,从而阻塞并触发死锁。
  2. 同步机制缺失main 函数启动 goroutine 后没有等待其完成,直接进入读取循环,可能因 goroutine 未及时发送数据而阻塞。

修复方案

使用 sync.WaitGroup 确保 goroutine 完成,并在发送数据后关闭通道。以下是修改后的代码:

package main

import (
	"fmt"
	"sync"
)

func main() {
	ch := make(chan int)
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := 0; i < 5; i++ {
			ch <- i
		}
		close(ch) // 关闭通道以通知接收方无更多数据
	}()

	// 启动另一个 goroutine 等待发送完成并关闭通道
	go func() {
		wg.Wait()
	}()

	// 从通道读取数据,直到通道关闭
	for num := range ch {
		fmt.Println(num)
	}
}

关键点说明

  • 使用 sync.WaitGroupwg.Add(1) 表示启动一个 goroutine,defer wg.Done() 在 goroutine 结束时减少计数。
  • 关闭通道:在发送完所有数据后调用 close(ch),这样 for range 循环会在通道关闭后自动退出,避免死锁。
  • 分离等待逻辑:通过另一个 goroutine 调用 wg.Wait() 来等待发送完成,避免阻塞主循环。在实际应用中,如果 main 函数只需读取数据,可直接在 goroutine 中关闭通道。

运行此代码将输出数字 0 到 4,然后正常退出,无死锁错误。

回到顶部