首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写到通道永远被阻塞

写到通道永远被阻塞
EN

Stack Overflow用户
提问于 2017-01-21 17:08:42
回答 1查看 2.1K关注 0票数 2

我被困在一种奇怪的情况下,对频道的写操作永远不会发生。

代码语言:javascript
复制
package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan int)
    s := make(chan bool)
    k := make(chan bool)
    fmt.Println("start")
    go func() {
    fmt.Println("routine 1")
        s <- true
    }()
    go func() {
    fmt.Println("routine 2")
        for {
            select {
            case  <-s :
                for i := 0; i < 3; i++ {
                    fmt.Println("before")
                    c <- i
                    fmt.Println("after")
                }       
            case <- k :
                fmt.Println("k ready")
                break
            }
        }
    }()

    go func() {
        fmt.Println("routine 3")
        for {
            select {
                case x := <- c :
                fmt.Println("x=", x)
                k <- true
                fmt.Println("k done")

            }
        }
    }()

    time.Sleep(1000 * time.Millisecond)
}

这是输出:

代码语言:javascript
复制
start
routine 1
routine 2
before
routine 3
x= 0
after
before

我不知道为什么写入通道k块,但是日志语句fmt.Println("k ready")从未被打印出来。

以下是我的想法:

  • go例程1将true写入通道的
  • go例程2将0写入通道c并等待,因为缓冲区大小为0,除非有人读取通道c,否则它将无法向其写入“1”。
  • go例程3进入图片,读取通道c(现在go例程2可以写到c,一旦转到例程2简历)打印x的值。现在应该可以写到K频道了,但这不是

据我所知,它应该能够写到通道k,然后戈鲁廷的案例2应该执行并打印"k就绪“。

有人能解释我为什么要写信给被封锁的频道吗?作为一个修复,我知道我可以增加通道c的缓冲区大小,所有的东西都会被打印出来,但是我不想修复这个问题,相反,我想了解这个场景。

一个很好的博客来理解上面的情况。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-21 17:21:40

你陷入僵局了。

  • goroutine 1写到s,然后退出
  • goroutine 2从s读取,并写入c
  • goroutine 3从c读取,然后写到k,这是因为没有从k读取的东西,因为在上面的k写中,k2被阻塞了。
  • goroutine 2再次写入c,该块作为goroutine 3仍然试图写入k,因此没有从c读取。

与您所说的相反,您没有1的缓冲区大小,缓冲区大小为零(即一个未缓冲的通道),所以写将阻塞,直到读取。这可能是你误解的根源。根据语言规范

可以使用内置函数make创建一个新的初始化通道值,该函数以通道类型和可选容量作为参数: 制造(chan int,100) 容量(以元素数计)设置通道中缓冲区的大小。如果容量为零或缺失,则信道未缓冲,只有当发送方和接收方都准备就绪时,通信才能成功。否则,如果缓冲区不满(发送)或非空(接收),则信道被缓冲,通信成功而不阻塞。一个零频道从来没有准备好进行交流。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41782133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档