为什么传入通道的值没有被 fmt.Println 打印出来?
Why is the value passed into the channel not being printed out by fmt.Println?
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://golang.org",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
for _, link := range links {
testRequest(link, c)
}
msg := <-c
fmt.Println(msg)
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}
Channels 应该是引用类型,出于某种原因,该函数没有向通道传递任何内容,因为每次我 运行 代码都会按预期打印出第一行,但程序不会't stop 运行ning 并且也不执行 fmt.Println(channel)
所以我的假设是没有值被传递到通道,因为它应该是,有什么原因吗?
您的程序在 for 第一个循环后卡住了,发送方尝试发送到通道,但接收方只能在循环完成后才能接收
//This loop will blocks until finished
for _, link := range links {
testRequest(link, c) // Try to send, receiver can't receive
}
//Until above loop finishs, this never excutes
msg := <-c
mt.Println(msg)
运行发送方循环go
所以接收方循环可以执行,但是你需要在所有工作完成之前防止主程序退出。
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
// This code will not blocks
go func() {
for _, link := range links {
testRequest(link, c)
}
}()
// Above code doesn't block, this code can excutes
for {
msg := <-c
fmt.Println(msg)
}
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}
对于无缓冲通道,testRequests() 中的写入将在您从 main() 中的通道读取之前阻塞。你陷入僵局了。通常你应该得到一个错误,通常去找出所有 goroutines 何时被阻止。不知道你为什么不。
您可能想 运行 在不同的 goroutine 中测试 Requests():
package main
import (
"fmt"
"net/http"
)
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://golang.org",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
go func() {
for _, link := range links {
testRequest(link, c)
}
close(c)
}()
for msg := range c {
fmt.Println(msg)
}
fmt.Println("Done handling request")
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://golang.org",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
for _, link := range links {
testRequest(link, c)
}
msg := <-c
fmt.Println(msg)
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}
Channels 应该是引用类型,出于某种原因,该函数没有向通道传递任何内容,因为每次我 运行 代码都会按预期打印出第一行,但程序不会't stop 运行ning 并且也不执行 fmt.Println(channel)
所以我的假设是没有值被传递到通道,因为它应该是,有什么原因吗?
您的程序在 for 第一个循环后卡住了,发送方尝试发送到通道,但接收方只能在循环完成后才能接收
//This loop will blocks until finished
for _, link := range links {
testRequest(link, c) // Try to send, receiver can't receive
}
//Until above loop finishs, this never excutes
msg := <-c
mt.Println(msg)
运行发送方循环go
所以接收方循环可以执行,但是你需要在所有工作完成之前防止主程序退出。
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
// This code will not blocks
go func() {
for _, link := range links {
testRequest(link, c)
}
}()
// Above code doesn't block, this code can excutes
for {
msg := <-c
fmt.Println(msg)
}
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}
对于无缓冲通道,testRequests() 中的写入将在您从 main() 中的通道读取之前阻塞。你陷入僵局了。通常你应该得到一个错误,通常去找出所有 goroutines 何时被阻止。不知道你为什么不。
您可能想 运行 在不同的 goroutine 中测试 Requests():
package main
import (
"fmt"
"net/http"
)
func main() {
links := []string{
"http://google.com",
"http://amazon.com",
"http://golang.org",
"http://yahoo.com",
"http://ebay.com",
}
c := make(chan string)
go func() {
for _, link := range links {
testRequest(link, c)
}
close(c)
}()
for msg := range c {
fmt.Println(msg)
}
fmt.Println("Done handling request")
}
func testRequest(s string, c chan string) {
_, err := http.Get(s)
if err != nil {
fmt.Println(s, "Is down presently")
c <- "Something might be down"
return
}
fmt.Println(s, "Is working perfectly")
c <- "Working great!"
}