首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Goroutine +通道执行命令

Goroutine +通道执行命令
EN

Stack Overflow用户
提问于 2022-02-22 09:28:12
回答 1查看 119关注 0票数 -1

我是刚接触过戈朗的人,我想深入了解channel的工作原理。在过去,我用.net做了一个基本的多线程程序,所以我现在有点像goroutine

我假设goroutine是某种线程(实际上是一个绿色线程),它将与其他goroutine并发运行,因此无法保证执行顺序

但是我不明白当你把goroutinechannel结合在一起的时候

我知道您可以使用channel来保证goroutine的执行顺序,因为它可以阻止goroutine

让我说我有这样的代码

代码语言:javascript
复制
func greet(c chan string) {

    fmt.Println("Before print 1st item")
    fmt.Println("Hello", <-c)
    fmt.Println("After print 1st item")

    fmt.Println("Before print 2nd item")
    fmt.Println("Hello", <-c)
    fmt.Println("After print 2nd  item")

}

func main() {
    fmt.Println("Main start")
    c := make(chan string)

     go greet(c)

    fmt.Println("Before insert 1st item")
    c <- "Alpha" // main goroutine blocked here and will be switched to another goroutine. Blocked because the channel is full or maybe I'm wrong here?
    fmt.Println("After insert 1st item")

    fmt.Println("Before insert 2nd item")
    c <- "Zebra" // why is it not blocked here ?
    fmt.Println("After insert 2nd item")

    time.Sleep(2 * time.Second)
    fmt.Println("Main end")
}

//Output
Main start
Before insert 1st item
Before print 1st item
Hello Alpha
After print 1st item
Before print 2nd item
After insert 1st item
Before insert 2nd item
After insert 2nd item // why is it printed here ???
Hello Zebra
After print 2nd  item
Main end

为什么印成那样??

代码语言:javascript
复制
// My expectation
Main start
Before insert 1st item
Before print 1st item
Hello Alpha
After print 1st item
Before print 2nd item
After insert 1st item
Before insert 2nd item
Hello Zebra
After print 2nd  item
After insert 2nd item 
Main end

据我所知,KeyPoint

  1. main gouroutine阻塞了这条线c <- "Alpha",因此它切换到greet goroutine
  2. greet goroutine将继续执行,直到在第二个fmt.Println("Hello", <-c)上阻塞为止。
  3. 现在,greet goroutine被阻塞,main goroutine没有被阻塞,因为channel中的字符串Alpha已经读取,并且将继续执行。

我的问题是,为什么main goroutine在这行c <- "Zebra"上没有被阻塞?

我期望它再次被阻塞,就像在步骤2中一样,并将切换到greet goroutine

基于这个文档

默认情况下,发送和接收块,直到另一方准备就绪。这允许goroutines在没有显式锁或条件变量的情况下同步。

EN

回答 1

Stack Overflow用户

发布于 2022-02-22 16:22:54

比方说频道就像一张桌子。当有人等着接受的时候,就像你想从桌子上拿东西一样。如果有什么东西,你拿着就走,如果什么都没有,你必须等待有人把它放在那里。当您想要在频道发送时,也会发生同样的情况。如果桌子上什么都没有,你只要把你所有的东西放出去,如果上面有什么东西,你必须等着有人拿着它放你的东西。(记住,你可以有一个有空间的频道来做更多的事情)。

在你获得解放的那一刻,你继续做你想做的事,不需要等待或同步。所以您不知道之前会发生什么,因为根据分配给您的处理周期,您将在其他例程之前或之后到达那里。

如果启动几次,就会看到不同的输出。

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

https://stackoverflow.com/questions/71218782

复制
相关文章

相似问题

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