goroutines死锁,需要一些解释吗

goroutines死锁,需要一些解释吗,go,deadlock,goroutine,Go,Deadlock,Goroutine,我想知道围棋在这里是如何运作的 问题1: go例程是否从主go例程/func继承了任何内容 问题2: 还想知道如果我把“hi whats up”发送到msg频道,为什么go例程在第13行没有收到 1 package main 2 3 import "fmt" 4 5 func main() { 6 msg := make(chan string, 2) //channel (bidirectional channel) of type string 7

我想知道围棋在这里是如何运作的

问题1: go例程是否从主go例程/func继承了任何内容

问题2: 还想知道如果我把“hi whats up”发送到msg频道,为什么go例程在第13行没有收到

  1 package main
  2 
  3 import "fmt"
  4 
  5 func main() {
  6     msg := make(chan string, 2) //channel (bidirectional channel) of type string
  7 
  8     msg <- "hi whats up"
  9     fmt.Println("*****I am main go routine*****")
 10 
 11     go func() {
 12         fmt.Println("*****HI ABHI *****\n")
 13         temp := <-msg
 14         fmt.Println(temp)
 15         msg <- "Hello from a goroutine!" //send a string through the channel
 16     }()
 17 
 18     fmt.Println("Main routine waiting for message")
 19 
 20     fmt.Println(<-msg) //receive the string from the channel
 21     fmt.Println(<-msg)
 22 }  
1主程序包
2.
3进口“fmt”
4.
5 func main(){
6 msg:=make(chan string,2)//string类型的通道(双向通道)
7.

8 msg您试图在同一频道上以两种方式发送消息,并且您不做任何事情来保证谁读取了哪些消息。在
函数
goroutine尝试从该频道读取消息之前,主goroutine完全有可能接收它发送的消息。如果发生这种情况,两个goroutine都会被stuck等待永远不会到达的消息


使用两个通道。

您试图在同一通道上以两种方式发送消息,并且您不做任何事情来保证谁读取了哪些消息。在
函数尝试从通道读取消息之前,主goroutine完全有可能接收它发送的消息。如果发生这种情况,两个goroutine尖牙被卡在等待永远不会到达的消息上


使用两个通道。

新启动的goroutine可以通过闭包从外部代码捕获变量,但不能继承任何内容


第13行上的通道接收和第20行上的通道接收之间存在竞争。如果第20行上的读取首先执行,它将消耗通道上的唯一值,最终,两个goroutine都被阻止从通道读取,因此出现死锁错误。如果您想从goroutine中获取一个值,最好使用另一个chan新启动的goroutine可以通过闭包从外部代码捕获变量,但在其他情况下不会继承任何内容


第13行上的通道接收和第20行上的通道接收之间存在竞争。如果第20行上的读取首先执行,它将消耗通道上的唯一值,最终,两个goroutine都被阻止从通道读取,因此出现死锁错误。如果您想从goroutine中获取一个值,最好使用另一个channel,而不是尝试在一个上对其进行排序。

以下是一个工作示例:

package main

import "fmt"

func main() {
    msg := make(chan string)
    go func() {
        temp := <-msg
        fmt.Println(temp)
        msg <- "Hello from a goroutine!"
    }()

    msg <- "hi whats up"
    fmt.Println(<-msg)
}
主程序包
输入“fmt”
func main(){
msg:=make(chan字符串)
go func(){

温度:=以下是一个工作示例:

package main

import "fmt"

func main() {
    msg := make(chan string)
    go func() {
        temp := <-msg
        fmt.Println(temp)
        msg <- "Hello from a goroutine!"
    }()

    msg <- "hi whats up"
    fmt.Println(<-msg)
}
主程序包
输入“fmt”
func main(){
msg:=make(chan字符串)
go func(){

temp:=与错误无关(目前),但您尝试接收通道三次,而您只尝试发送两条消息。这似乎是非常错误的。代码行14的第二部分永远没有机会执行,因为当main func返回时,go程序结束。您可以添加一个简单的
time.Sleep(time.second)
(记住在第16行之后导入“time”
)以查看效果。与错误无关(目前)但是您尝试接收频道三次,而只发送两条消息。这似乎是非常错误的。代码行14的第二部分永远没有机会执行,因为当main func返回时,go程序结束。您可以添加一个简单的
time.Sleep(time.second)
(记住
导入“time”
)在第16行之后查看效果。如果我在调用“go例程”之前写入msg通道,为什么它不起作用???@invicus在这段代码中,这是因为它没有缓冲,没有从中读取任何内容(goroutine尚未启动)。如果我在调用“go例程”之前写入msg通道,为什么它不起作用???@Invictus在这段代码中,这是因为它是无缓冲的,没有从中读取任何内容(goroutine尚未启动)。msg:=make(chan string,2)msg如果看我的评论,我已经编辑了程序,即使是现在的“fmt.Println(temp)”不print@Invictus请将代码编辑成问题并格式化。此处大部分内容不可读。@Invictus:程序在主goroutine结束时结束。msg:=make(chan string,2)msg如果看我的评论,我已经编辑了程序,即使是现在的“fmt.Println(temp)”不print@Invictus请将代码编辑成问题并格式化。这里大部分内容不可读。@Invictus:程序在主goroutine结束时结束。对于第1点,如果新go例程没有从主go例程继承,那么“新go例程”如何获得消息通道???@Invictus,这就是我们所说的“闭包”.用谷歌搜索一下。但是,我没有通过“msg chan”在新围棋例程的闭包中,那么新围棋例程是如何得到它的呢?@invitus很难在这里解释整个闭包过程,但简单地说,goroutine作为一个函数,可以访问otter scope的变量,这是主函数。对于点#1,如果新围棋例程没有从主围棋例程继承,那么“新的围棋程序”获得msg频道???@invicutus,这就是我们所说的“关闭”。用谷歌搜索它。但是,我没有通过“msg频道”“在新围棋程序的闭包中,那么新围棋程序是如何得到它的?”@invitus很难在这里解释整个闭包过程,但简单地说,goroutine作为一个函数,可以访问otter scope的变量,这是主要的函数。