无法找到死锁的原因

huangapple go评论76阅读模式
英文:

Unable to find reason for go deadlock

问题

无法找到代码死锁的原因。这里的目标是在收到信号后,使工作协程执行一些工作。

如果从代码中移除signalStream通道,它可以正常工作。但是当引入该通道时,它会发生死锁。不确定原因。如果有任何工具可以解释死锁的发生,那将会有所帮助。

package main

import (
	"log"
	"sync"
)

const jobs = 10
const workers = 5

var wg sync.WaitGroup

func main() {

	// 创建通道
	dataStream := make(chan interface{})
	signalStream := make(chan interface{})

	// 生成工作协程
	for i := 1; i <= workers; i++ {
		wg.Add(1)
		go worker(dataStream, signalStream, i*100)
	}

	// 生成任务
	for i := 1; i <= jobs; i++ {
		dataStream <- i
	}
	close(dataStream)

	// 开始消费数据
	close(signalStream)

	wg.Wait()

}

func worker(c <-chan interface{}, s <-chan interface{}, id int) {
	defer wg.Done()
	<-s

	for i := range c {
		log.Printf("routine - %d - %d \n", id, i)
	}

}
英文:

Unable to find a reason as to why this code deadlocks. The aim here is make the worker go routines do some work only after they are signaled.

If the signalStream channel is removed from the code, it works fine. But when this is introduced, it deadlocks. Not sure the reason for this. Also if there are any tools to explain the occurrence of deadlock, it would help.

package main

import (
	&quot;log&quot;
	&quot;sync&quot;
)

const jobs = 10
const workers = 5

var wg sync.WaitGroup

func main() {

	// create channel
	dataStream := make(chan interface{})
	signalStream := make(chan interface{})

	// Generate workers

	for i := 1; i &lt;= workers; i++ {
		wg.Add(1)
		go worker(dataStream, signalStream, i*100)
	}

	// Generate jobs

	for i := 1; i &lt;= jobs; i++ {
		dataStream &lt;- i
	}
	close(dataStream)

	// start consuming data
	close(signalStream)

	wg.Wait()

}

func worker(c &lt;-chan interface{}, s &lt;-chan interface{}, id int) {
	defer wg.Done()
	&lt;-s

	for i := range c {
		log.Printf(&quot;routine - %d - %d \n&quot;, id, i)
	}

}

答案1

得分: 1

将作业生成部分放入一个独立的goroutine中,即将整个jobs循环放入goroutine中。如果不这样做,dataStream <- i将会阻塞,你的程序将永远无法"开始消费数据"。

// 生成作业
go func() {
	for i := 1; i <= jobs; i++ {
		dataStream <- i
	}
	close(dataStream)
}()

链接:https://go.dev/play/p/ChlbsJlgwdE

英文:

Generate the jobs in a separate gorouine, i.e. put the whole jobs loop into a goroutine. If you don't then dataStream &lt;- i will block and your program will never "start consuming data"

// Generate jobs
go func() {
	for i := 1; i &lt;= jobs; i++ {
		dataStream &lt;- i
	}
	close(dataStream)
}()

https://go.dev/play/p/ChlbsJlgwdE

huangapple
  • 本文由 发表于 2022年3月25日 14:34:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/71613010.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定