go routine dead lock?

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

go routine dead lock?

问题

我是你的中文翻译助手,以下是你提供的代码的翻译:

package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	c := make(chan string)
	work := make(chan int, 1)
	clvl := runtime.NumCPU()
	count := 0
	for i := 0; i < clvl; i++ {
		go func(i int) {
			for jdId := range work {
				time.Sleep(time.Second * 1)
				c <- fmt.Sprintf("done %d", jdId)
			}
		}(i)
	}

	go func() {
		for i := 0; i < 10; i++ {
			work <- i
		}

		close(work)
	}()

	for resp := range c {
		fmt.Println(resp, count)
		count += 1
	}
}

这段代码是一个使用goroutine和channel的示例。它创建了两个通道(cwork),并使用goroutine并发地执行任务。在主函数中,它首先创建了一个用于接收结果的通道c,以及一个带有缓冲区的通道work。然后,它根据计算机的CPU核心数量创建了相应数量的goroutine,并将任务分配给它们执行。每个goroutine都会从work通道接收任务,并在执行任务后将结果发送到c通道。主函数通过从c通道接收结果,并打印出来。

这段代码的目的是模拟并发执行任务,并在任务完成后打印结果。

英文:

I am new to golang, and I am puzzled with this deadlock (run here)

package main

import (
	&quot;fmt&quot;
	&quot;runtime&quot;
	&quot;time&quot;
)

func main() {
	c := make(chan string)
	work := make(chan int, 1)
	clvl := runtime.NumCPU()
	count := 0
	for i := 0; i &lt; clvl; i++ {
		go func(i int) {
			for jdId := range work {
				time.Sleep(time.Second * 1)
				c &lt;- fmt.Sprintf(&quot;done %d&quot;, jdId)
			}
		}(i)
	}

	go func() {
		for i := 0; i &lt; 10; i++ {
			work &lt;- i
		}

		close(work)
	}()

	for resp := range c {
		fmt.Println(resp, count)
		count += 1
	}
}

答案1

得分: 2

你没有关闭c,所以你的for range循环会一直等待。像这样关闭它:

var wg sync.WaitGroup
for i := 0; i < clvl; i++ {
    wg.Add(1)
    go func(i int) {
        defer wg.Done()
        for jdId := range work {
            time.Sleep(time.Second * 1)
            c <- fmt.Sprintf("done %d", jdId)
        }
    }(i)
}

go func() {
    for i := 0; i < 10; i++ {
        work <- i
    }

    close(work)
    wg.Wait()
    close(c)
}()

编辑:修复了恐慌,谢谢Crast的指正。

英文:

You never close c, so your for range loop waits forever. Close it like this:

var wg sync.WaitGroup
for i := 0; i &lt; clvl; i++ {
    wg.Add(1)
    go func(i int) {
        defer wg.Done()
        for jdId := range work {
            time.Sleep(time.Second * 1)
            c &lt;- fmt.Sprintf(&quot;done %d&quot;, jdId)
        }
    }(i)
}

go func() {
    for i := 0; i &lt; 10; i++ {
        work &lt;- i
    }

    close(work)
    wg.Wait()
    close(c)
}()

EDIT: Fixed the panic, thanks Crast

huangapple
  • 本文由 发表于 2016年1月15日 17:19:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/34807804.html
匿名

发表评论

匿名网友

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

确定