2021-03-10

# goroutine学习笔记

个人将《go程序设计》p182中的例程做了些许修改。整个过程中有以下几个问题

- 将缓冲通道改成无缓冲通道后的goroutine泄露问题

```go

var response = make(chan string, 3)

func request(url string) string {

    switch url {

    case "europe.gopl.io":

        time.Sleep(5 * time.Second)

        log.Println(url)

        break

    case "americas.gopl.io":

        time.Sleep(7 * time.Second)

        log.Println(url)

        break

    case "asia.gopl.io":

        time.Sleep(3 * time.Second)

        log.Println(url)

        break

    }

    return url

}

 

func mirrResponse() string {

    go func() { response <- request("asia.gopl.io") }()

    go func() { response <- request("europe.gopl.io") }()

    go func() { response <- request("americas.gopl.io") }()

    fmt.Printf("channel len:%d\n", len(response))

    fmt.Printf("channel cap:%d\n", cap(response))

    // <-response

    // <-response

    return <-response

}

 

func main() {

    for i := 0; i < 10; i++ {

        fmt.Println("resp_url:", mirrResponse())

        fmt.Printf("goroutineNum:%d\n", runtime.NumGoroutine())

    }

}

```

运行以上程序,通过在main函数中输出运行协程数量,可以观察到携程数量不断增加。这里主要原因是:因为只有一个<-reponse,所以每次运行只会阻塞等待第一个"asia.gopl.io"的response返回,但是后台剩下的两个携程还是会运行;且由于没有等待其执行完后运行,所以每次运行mirrResponse函数时都会新增两个运行的携程,故NumGoroutine的输出每次+2

 

- 修改实验

```go

func mirrResponse() string {

    go func() { response <- request("asia.gopl.io") }()

    go func() { response <- request("europe.gopl.io") }()

    go func() { response <- request("americas.gopl.io") }()

    fmt.Printf("channel len:%d\n", len(response))

    fmt.Printf("channel cap:%d\n", cap(response))

    // <-response

    <-response

    return <-response

}

```

当消费者(<-reponse)==2时,mirrResponse会阻塞等待第二个协程执行完后再返回,且由于休眠的时间不同,始终有一个协程处于睡眠状态,加上main所在的主协程,故总是能输出运行协程数=2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值