当前位置: 首页 > 面试题库 >

遍历通道时关闭通道的最佳时间

章晋鹏
2023-03-14
问题内容

我正在玩Golang,我创建了这个小应用程序,使用goroutines进行了多个并发的api调用。

当应用程序运行时,调用完成后,该应用程序将卡住,这是有道理的,因为由于通道未关闭,无法退出 范围c 循环。

我不确定在哪种情况下可以更好地关闭该通道。

package main

import "fmt"
import "net/http"

func main() {
    links := []string{
        "https://github.com/fabpot",
        "https://github.com/andrew",
        "https://github.com/taylorotwell",
        "https://github.com/egoist",
        "https://github.com/HugoGiraudel",
    }

    checkUrls(links)
}

func checkUrls(urls []string) {
    c := make(chan string)

    for _, link := range urls {
        go checkUrl(link, c)
    }

    for msg := range c {
        fmt.Println(msg)
    }

    close(c) //this won't get hit
}

func checkUrl(url string, c chan string) {
    _, err := http.Get(url)

    if err != nil {
        c <- "We could not reach:" + url
    } else {
        c <- "Success reaching the website:" + url
    }
}

问题答案:

当没有更多值要发送时,您将关闭通道,因此在这种情况下,所有checkUrlgoroutine已完成。

var wg sync.WaitGroup

func checkUrls(urls []string) {
    c := make(chan string)

    for _, link := range urls {
        wg.Add(1)
        go checkUrl(link, c)
    }

    go func() {
        wg.Wait()
        close(c)
    }()

    for msg := range c {
        fmt.Println(msg)
    }
}

func checkUrl(url string, c chan string) {
    defer wg.Done()
    _, err := http.Get(url)

    if err != nil {
        c <- "We could not reach:" + url
    } else {
        c <- "Success reaching the website:" + url
    }
}

(请注意,errorfrom
http.Get仅将反映连接和协议错误。如果您也期望这些错误,则它不会包含http服务器错误,您必须了解如何检查路径,而不仅仅是主机。)



 类似资料:
  • 我们知道range函数可以遍历数组,切片,字典等。这里我们还可以使用range函数来遍历通道以接收通道数据。 package main import "fmt" func main() { // 我们遍历queue通道里面的两个数据 queue := make(chan string, 2) queue <- "one" queue <- "two" clo

  • 关闭通道的意思是该通道将不再允许写入数据。这个方法可以让通道数据的接受端知道数据已经全部发送完成了。 package main import "fmt" // 在这个例子中,我们使用通道jobs在main函数所在的协程和一个数据 // 接收端所在的协程通信。当我们数据发送完成后,我们关闭jobs通道 func main() { jobs := make(chan int, 5) d

  • 问题内容: 不知道频道 长度时,我无法关闭频道 它给我错误 这是合乎逻辑的-当第二个goroutine关闭通道试图发送给它时,它关闭了它。在这种情况下关闭渠道的最佳方法是什么? 问题答案: 通道关闭后,您将无法在该通道上发送更多值,否则会出现混乱。这就是您的经验。 这是因为您启动了使用同一个通道的多个goroutine,并且它们在该通道上发送值。然后关闭每个通道。而且由于它们未同步,因此一旦第一个

  • 我从两个通道中获得了多个的goroutine:一个chan提供数据,一个chan提供信号(类似于done/quit通道)。 我使用signals通道来捕获信号(杀死)并优雅地关闭Goroutines。 当我终止正在运行的进程时,我会看到来自的打印消息。我预计,一旦通道关闭,goroutines将thecase并返回。 但他们不停地奔跑;它们继续处理中的项。好像被忽视了。我在这里漏掉了什么?频道不是

  • 我刚刚将ProjectReactor.io从旧反应堆[Core:3.0.1.发行版,Netty:0.5.2.发行版]升级到新反应堆[Core:3.0.4.发行版,Netty:0.6.0.发行版]。 我打开了一个TcpClient连接并希望稍后关闭它。 在我使用的旧版本中 断开我的客户端与服务器的连接。 新版本中是否有对等调用?我找不到一个! 在使用创建TcpClient时,我对获得的和尝试了以下操

  • 我有一个多线程应用程序,它将传入的消息发布到rabbitmq交换。使用rabbitmq java客户端,我在应用程序启动时创建一个rabbitmq连接,并在所有线程之间共享它。每个线程都创建一个新通道(threadlocal),这样通道就不会像rabbitmq文档所建议的那样在多个线程之间共享。我正在使用netty,我看到相同数量的rabbitmq通道被创建为netty通道管道线程。到目前为止还不