以下是要翻译的内容: 以下的Go代码中是否存在死锁?尽管没有输出。

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

Is there a dead lock in the following go code? Not output though

问题

我正在运行以下的Go代码,但是它没有产生输出:

package main

import "fmt"
import "time"

func Wait(){
    time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string){
    fmt.Println("Running Print go-routine")
    for{
        fmt.Println("len(c): ", len(c))
        str := <- c
        fmt.Println(str)
    }
}

func main() {
    c := make(chan string, 4)
    c <- "0"
    c <- "1"
    c <- "2"
    c <- "3"
    Wait()
    fmt.Println("Before go Print(c)")
    go Print(c)
    fmt.Println("After go Print(c)")
}

是否发生了死锁?Print(c)函数甚至没有被调用...?这对我来说非常奇怪。
在Go Playground中的链接是:http://play.golang.org/p/tDjEJKwkRJ

英文:

I am running the following go code and it doesn't produce output:

package main

import &quot;fmt&quot;
//import &quot;strconv&quot;
import &quot;time&quot;

func Wait(){
	time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string){
	fmt.Println(&quot;Running Print go-routine&quot;)
	for{
		fmt.Println(&quot;len(c): &quot;, len(c))
		str := &lt;- c
		fmt.Println(str)
	}
}

func main() {
	c := make(chan string, 4)
	c &lt;- &quot;0&quot;
	c &lt;- &quot;1&quot;
	c &lt;- &quot;2&quot;
	c &lt;- &quot;3&quot;
	Wait()
	fmt.Println(&quot;Before go Print(c)&quot;)
	go Print(c)
	fmt.Println(&quot;After go Print(c)&quot;)
}

Is there a deadlock? The Print(c) function is not even called...? Its very strange to me.
The link to it in go playground is: http://play.golang.org/p/tDjEJKwkRJ

答案1

得分: 2

没有错误,Print()函数在一个goroutine中被调用,但是主程序在此之后立即退出...所以goroutine被终止。

阅读这个讲座:Go并发模式(或者更好地,观看它的视频),以了解通道和goroutine的工作原理。

请记住,当主函数返回时,程序已经结束。

英文:

There isn't an error, the Print() function is called in a goroutine, but the main program is exiting right after that... so the goroutine is terminated.

Read this talk: Go Concurrency Patterns (or better, view it's video), to understand how channels and goroutines work.

Keep in mind that the program is finished when the main function returns.

答案2

得分: 2

main函数调用返回时,程序退出。它不会等待其他(非main)goroutine 完成。

go Print(c)语句之后,稍后调用你的Wait函数。例如,

package main

import (
	"fmt"
	"time"
)

func Wait() {
	time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string) {
	fmt.Println("Running Print go-routine")
	for {
		fmt.Println("len(c): ", len(c))
		str := <-c
		fmt.Println(str)
	}
}

func main() {
	c := make(chan string, 4)
	c <- "0"
	c <- "1"
	c <- "2"
	c <- "3"
	fmt.Println("Before go Print(c)")
	go Print(c)
	Wait()
	fmt.Println("After go Print(c)")
}

输出:

Before go Print(c)
Running Print go-routine
len(c):  4
0
len(c):  3
1
len(c):  2
2
len(c):  1
3
len(c):  0
After go Print(c)

Go编程语言规范

程序执行

通过将一个名为main的单个未导入的包与其导入的所有包进行链接,可以创建一个完整的程序,其中包括传递性。主包必须具有包名main,并声明一个不带参数且不返回值的main函数。

func main() { … }

程序的执行从初始化主包开始,然后调用main函数。当该函数调用返回时,程序退出。它不会等待其他(非main)goroutine 完成。

英文:

When the main function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

Call your Wait function later, after the go Print(c) statement. For example,

package main

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

func Wait() {
	time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string) {
	fmt.Println(&quot;Running Print go-routine&quot;)
	for {
		fmt.Println(&quot;len(c): &quot;, len(c))
		str := &lt;-c
		fmt.Println(str)
	}
}

func main() {
	c := make(chan string, 4)
	c &lt;- &quot;0&quot;
	c &lt;- &quot;1&quot;
	c &lt;- &quot;2&quot;
	c &lt;- &quot;3&quot;
	fmt.Println(&quot;Before go Print(c)&quot;)
	go Print(c)
	Wait()
	fmt.Println(&quot;After go Print(c)&quot;)
}

Output:

Before go Print(c)
Running Print go-routine
len(c):  4
0
len(c):  3
1
len(c):  2
2
len(c):  1
3
len(c):  0
After go Print(c)

> The Go Programming Language Specification
>
> Program execution
>
> A complete program is created by linking a single, unimported package
> called the main package with all the packages it imports,
> transitively. The main package must have package name main and declare
> a function main that takes no arguments and returns no value.
>
> func main() { … }
>
> Program execution begins by initializing the main package and then
> invoking the function main. When that function invocation returns, the
> program exits. It does not wait for other (non-main) goroutines to
> complete.

huangapple
  • 本文由 发表于 2014年7月22日 03:10:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/24872823.html
匿名

发表评论

匿名网友

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

确定