当我使用命令 go run main.go
运行
Program 1时,它会因错误
all goroutines are asleep - deadlock!
终止,而 Program 2 继续等待并且不会终止。我们没有调用 checkLink
函数,但我们仍然看到不同的行为。你能解释一下吗?
此外,当我运行
go build main.go
的程序2的输出的可执行文件时,它被杀死并删除了可执行文件。
节目1
package main
import (
"fmt"
)
func main() {
c := make(chan int)
c <- 4
x := <-c
fmt.Println(x)
}
节目2
package main
import (
"fmt"
"net/http"
)
func main() {
c := make(chan int)
c <- 4
x := <-c
fmt.Println(x)
}
func checkLink(link string, c chan string) {
fmt.Println("checking", link)
_, err := http.Get(link)
if err != nil {
c <- link + " is down"
return
}
c <- link + " is up"
}
注意:我在 MacO 上运行此程序,shell 是 ZSH
您的 Go 程序似乎由于通道使用不当而遇到了死锁。
在程序 1 和程序 2 中,您都使用 make(chan int) 创建一个无缓冲通道 c。当您尝试发送值时 (c <- 4) on an unbuffered channel without a corresponding receiver, or when there's no receiver ready to receive the value sent on the channel, a deadlock occurs. This is because sending to an unbuffered channel blocks until there's a receiver ready to receive the value.
package main
import (
"fmt"
)
func main() {
c := make(chan int) // unbuffered channel
c <- 4 // attempting to send to an unbuffered channel without a receiver ready
x := <-c // this line will never be reached due to the deadlock above
fmt.Println(x)
}
这是上述代码的更正版本
package main
import (
"fmt"
)
func main() {
c := make(chan int)
go func() {
c <- 4 // Send value on the channel
}()
x := <-c // Receive value from the channel
fmt.Println(x)
}
在程序 1 中,我们使用 go func() {...}() 将通道操作包装在匿名 goroutine 中。这允许发送操作 c <- 4 to happen concurrently with the receiving operation x := <-c, preventing the deadlock
程序2的更正版本。
package main
import (
"fmt"
"net/http"
)
func main() {
c := make(chan string)
go checkLink("http://example.com", c)
result := <-c
fmt.Println(result)
}
func checkLink(link string, c chan string) {
fmt.Println("checking", link)
_, err := http.Get(link)
if err != nil {
c <- link + " is down"
return
}
c <- link + " is up"
}