去lang复用所有goroutines睡着了 - 僵局 [英] Go lang multiplexing all goroutines are asleep - deadlock
问题描述
package main $ 使用多个go例程创建fan-in函数返回channel这里是我的代码。 b
$ b进口(
fmt
数学/兰特
同步
时间
)
var wg,wg2 sync.WaitGroup
func main(){
final:= talk(boring(Joe),boring(Ann))
for我:= 0;我< 10; i ++ {
fmt.Println(< -final)
}
fmt.Println(你们都很无聊,我要离开)
}
func talk(input1,input2< -chan string)< -chan string {
out:= make(chan string)
go func(){
wg.Add(1 )
用于{
出< - < -input1
}
}()
去func(){
wg.Add(1)
为{
out < - <-input2
}
}()
wg.Done()
关闭(出)
返回
}
func boring(msg string)< -chan string {
c:= make(chan string)
for i:= 0;我< 5; i ++ {
c< - fmt.Sprintf(%s%d \ n,msg,i)
time.Sleep(time.Duration(rand.Intn(1e3))* time.Millisecond )
}
return c
}
但我得到运行以上代码后出错
所有goroutines都睡着了 - 死锁
我试图关闭频道,但仍然给了我错误。我曾尝试将无聊的返回频道分配给Joe和Ann,然后通过这些频道进行多路复用的功能通话,但仍然没有成功。我很新的去了解这个概念不清楚的渠道。
select 语句允许一个goroutine等待多次通信
操作。
选择
直到其中一个案例可以运行,然后执行该
案例。
package main
$ b它随机选择一个。 b
$ b :=说话(无聊(乔),无聊(安))
为我:= 0;我< 10; i ++ {
fmt.Println(< -final)
}
fmt.Println(你们都很无聊,我要离开)
}
func talk(input1,input2< -chan string)< -chan string {
c:= make(chan string)
func(){
for {
选择{
case s:=< -input1:
c< - s
case s:=< -input2:
c< - s
}
}
}()
return c
}
func boring(msg string)< -chan string {
c:= make chan字符串)
去func(){
for i:= 0;我< 5; i ++ {
c< - fmt.Sprintf(%s:%d,msg,i)
time.Sleep(time.Duration(rand.Intn(1e3))* time.Millisecond)
$(b
code
$ b $ p > 试玩Playground
编辑:
在给出的例子中, boring
函数不使用goroutine for重复发送频道将永远阻止,因为:
https://tour.golang.org / concurrency / 2
默认情况下,发送和接收阻塞,直到另一方准备好。
这允许goroutines在没有显式锁定或
条件变量的情况下进行同步。
另外, wg.Done()
需要成为goroutine的一部分。
通过执行上述更改,我得到了它的工作: https://play.golang.org/p/YN0kfBO6iT
I wants to create a fan-in function using multiple go routines returning channel here is my code.
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg, wg2 sync.WaitGroup
func main() {
final := talk(boring("Joe"), boring("Ann"))
for i := 0; i < 10; i++ {
fmt.Println(<-final)
}
fmt.Println("You are both boring I'm leaving")
}
func talk(input1, input2 <-chan string) <-chan string {
out := make(chan string)
go func() {
wg.Add(1)
for {
out <- <-input1
}
}()
go func() {
wg.Add(1)
for {
out <- <-input2
}
}()
wg.Done()
close(out)
return out
}
func boring(msg string) <-chan string {
c := make(chan string)
for i := 0; i < 5; i++ {
c <- fmt.Sprintf("%s%d\n", msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
return c
}
But I got an error after running above code
all goroutines are asleep - deadlock
I have tried to close channels but still it is giving me the error. I have tried to assign boring returned channels to Joe and Ann and then pass those channels to talk function for multiplexing still no success. I am new to go learning channels not clear on this concept.
解决方案 Instead of wait groups, you can use select
: https://tour.golang.org/concurrency/5
The select
statement lets a goroutine wait on multiple communication
operations.
A select
blocks until one of its cases can run, then it executes that
case. It chooses one at random if multiple are ready.
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
final := talk(boring("Joe"), boring("Ann"))
for i := 0; i < 10; i++ {
fmt.Println(<-final)
}
fmt.Println("You are both boring I'm leaving")
}
func talk(input1, input2 <-chan string) <-chan string {
c := make(chan string)
go func() {
for {
select {
case s := <-input1:
c <- s
case s := <-input2:
c <- s
}
}
}()
return c
}
func boring(msg string) <-chan string {
c := make(chan string)
go func() {
for i := 0; i < 5; i++ {
c <- fmt.Sprintf("%s: %d", msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}()
return c
}
Edit:
In your given example, boring
function doesn't use goroutine for repeated send over channel which will block forever, because:
https://tour.golang.org/concurrency/2
By default, sends and receives block until the other side is ready.
This allows goroutines to synchronize without explicit locks or
condition variables.
Also, wg.Done()
needs to be part of goroutine.
I got it working by doing above changes: https://play.golang.org/p/YN0kfBO6iT
这篇关于去lang复用所有goroutines睡着了 - 僵局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!