2017-06-11 33 views
-1

例如:我可以使用make(chan someStruct)吗?

type name struct { 
    name string 
    age int 
} 

func main() { 
     c := make(chan name) 

     c <- name{"sfsaf", 1} 
     a, b := <- c 

     close(c) 
} 

其结果是:

fatal error: all goroutines are asleep - deadlock!

我想通过信道来传递值。我该怎么办?

+0

[通道](https://golang.org/ref/spec#ChannelType)在并发函数之间进行通信时使用。在您的示例中,写入和读取操作不是并发的,因此导致死锁。在'goroutine'内执行读或写操作,例如'go func(){c < - name {“sfsaf”,1}}()'。 – putu

+0

https://stackoverflow.com/questions/36505012/go-fatal-error-all-goroutines-are-asleep-deadlock可能的重复。 –

+0

@CeriseLimón这不是一个重复的问题。那个没有说明如何使用'make(chan somestruct)'。 –

回答

2

是的,你可以通过结构。但是,这不是您的OP中的问题。

通道期望receiver被阻止,等待sender。这是通过Goroutines完成的。

当没有接收器准备好接收时,您在频道上发送了一个值。那是什么导致了你的僵局。

因此,将您的发件人包裹在goroutine中,这将不会立即执行。

package main 

import (
    "fmt" 
) 

type name struct { 
    name string 
    age int 
} 

func main() { 
    c := make(chan name) 

    go func() { 
     c <- name{"sfsaf", 1} 
     close(c) 
    }() 

    for n := range c { 
     fmt.Println(n) 
    } 

    fmt.Println("channel was closed (all done!).") 
} 

看到它在操场:https://play.golang.org/p/uaSuCaB4Ms

这工作,因为发件人的够程不执行呢。直到当前的goroutine执行被阻止。

而且我们在for n := range c循环中被阻塞。这是接收者,坐着等待价值观。 (这是使用for循环遍历通道值的常见模式,因为它将坐下并阻塞,等待值)。

因此,现在我们被阻止等待在for循环中接收值,现在内联输入将执行,以便在通道上发送我们的值。

此外,我们遵循安全做法,收拾好自己和close(c)的频道,发出for循环的信号或select声明将不会有更多的值发送。 发件人总是关闭,从来没有收件人。这是for范围循环用于退出for循环的模式,并继续执行其余代码。


作为一个方面说明,您通过传递struct的值而不是指针来做得很好。

如果你传递了一个指针,你必须在对象周围实现一些互斥锁来防止R/W恐慌。

Do not communicate by sharing memory; instead, share memory by communicating.

棒路过值,而不是指针,围绕你的渠道,够程,并从中获益。

相关问题