使用新的和频道去

时间:2017-04-06 22:39:00

标签: go

我在下面的技术演讲中找到了代码片段,我对一件事情有点困惑。

table <- new(Ball)之前应go player("ping", table)放置吗? 为什么我们甚至需要table <- new(Ball)?我认为table := make(chan *Ball)已经创建了频道。 这与死锁有关吗?

type Ball struct { hits int }

fun main() {
    table := make(chan *Ball)
    go player("ping", table)
    go player("pong", table)
    table <- new(Ball) // game on; toss the ball
    time.Sleep(1*time.Second)
    <-table // game over; grab the ball
}

func player(name string, table chan *Ball)
    for {
        ball := <-table
        ball.hits++
        fmt.println(name, ball.hits)
        time.Sleep(100 * time.Millisecond)
        table <- ball
    }
}

1 个答案:

答案 0 :(得分:5)

<-运算符是在通道中放置内容或将其取出的内容。它所在的一面显示它是否被放入或取出。因为通道没有大小,它实际上不能“保持”和项目,它会使go funcs阻塞,直到通道中放置了某些内容。双方(插入和移除)阻塞在没有大小的通道上,因此如果您尝试在没有接收器时插入某些东西,它会阻塞直到有一个接收器。在此特定代码中,player func会将其<- table删除并将其放回table <-

关于移动table <- new(Ball)的问题。如果你试图在没有接球手的情况下发球,那么主力球会等待接球。没有大小的通道更像是“处理”对象,因为没有涉及存储。相反,如果它是用缓冲区大小创建的,例如table := make(chan *Ball, 1),当它已经有1个项目时,它只会阻塞(与之前相同)。所以如果你用一个缓冲区创建它,但是试图在go funcs之前放置2个球,它会像以前一样死锁。

https://play.golang.org/p/zrN0D8IYnn