当我不使用go关键字时,函数不起作用

时间:2016-03-20 01:22:00

标签: go concurrency

在此功能中,您可以看到我使用go关键字。

package main

import (
    "fmt"
    "math"
)

func main() {
    c := make(chan string)
    go findGreatestDivisor(4, c)
    for i := 0; i <= 1; i++ {
        fmt.Println(<-c)
    }
}

func findGreatestDivisor(num float64, c chan string) {
    var counter float64 = 10000
    for i := 9999; i > 0; i-- {
        if math.Mod(num, counter) == 0 {
            fmt.Println("Check..", math.Mod(4, 1))
            c <- fmt.Sprintf("%f is divisble by %d", num, i)
        }
        counter--
    }

}

有效。它给了我最大的整数。但现在我好奇并删除了我在这里调用函数的go关键字

go findGreatestDivisor(4,c)

当我做的时候

findGreatestDivisor(4,c)

它给了我错误

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]: main.findGreatestDivisor(0x4010000000000000,
0xc82001a0c0)
       /home/ubuntu/workspace/test.go:21 +0x37c main.main()
       /home/ubuntu/workspace/test.go:10 +0x61 exit status 2

为什么?

1 个答案:

答案 0 :(得分:2)

  

The Go Programming Language Specification

     

Send statements

     

send语句在通道上发送值。频道表达   必须是通道类型,通道方向必须允许发送   操作,以及要发送的值的类型必须可分配给   频道的元素类型。

SendStmt = Channel "<-" Expression .
Channel  = Expression .
     

之前评估通道和值表达式   沟通开始了。通信阻塞,直到发送可以继续。   如果接收器准备就绪,则可以继续在无缓冲信道上发送。一个   如果缓冲区中有空间,则可以继续发送缓冲通道。   关闭通道上的发送通过导致运行时恐慌而继续。一个   永远发送一个零通道块。

ch <- 3  // send value 3 to channel ch

findGreatestDivisor

c := make(chan string)
findGreatestDivisor(4,c)

您尝试发送无缓冲的频道c

c <- fmt.Sprintf("%f is divisble by %d", num, i)

但通信阻止,直到发送可以继续。如果接收器准备就绪,则可以继续在无缓冲信道上发送。没有准备好接收器。

在频道c上收到

fmt.Println(<-c)
在你从findGreatestDivisor返回之前,

准备好了。那太晚了。