为了账号安全,请及时绑定邮箱和手机立即绑定

未从戈鲁廷获得预期输出

未从戈鲁廷获得预期输出

Go
慕标5832272 2022-09-19 14:59:05
我在(https://www.geeksforgeeks.org/channel-in-golang/)上读到:“在信道中,发送和接收操作阻塞,直到另一端默认未就绪。它允许戈鲁廷在没有显式锁或条件变量的情况下相互同步。为了测试上面的语句,我编写了一个示例程序,如下所述:程序:package mainimport (    "fmt"    "sync"    "time")func myFunc(ch chan int) {    fmt.Println("Inside goroutine:: myFunc()")    fmt.Println(10 + <-ch) //<-- According to rule, control will be blocked here until 'ch' sends some data so that it will be received in our myFunc() go routine.}func main() {    fmt.Println("Start Main method")    // Creating a channel    ch := make(chan int)    go myFunc(ch) //<-- This go routine started in a new thread    time.Sleep(2 * time.Second) //<--- introduced a Sleep of 2 seconds to ensure that myFunc() go routine executes before main thread    ch <- 10    fmt.Println("End Main method")}我期待下面的输出:Start Main methodInside goroutine:: myFunc()20End Main method但是,实际接收的输出是:Start Main methodInside goroutine:: myFunc()End Main method为什么通过通道发送的值没有打印出来?我认为,这是因为主线程首先完成了它的执行,因此,所有其他goroutine也终止了。如果是这样的话,那么,为什么规则说 - 它允许goroutine在没有显式锁或条件变量的情况下相互同步。因为,为了获得预期的输出,我必须使用告诉主线程等待另一个 goroutine 完成。这不是违反了上述规则,因为我以等待组的形式使用锁?sync.WaitGroupPS:我正在学习戈朗。所以,如果我完全理解了这个概念,请原谅。
查看完整描述

4 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

试试这个,使用你的代码作为基础


package main


import (

    "fmt"

    "time"

)


func myFunc(ch chan int, done chan struct{}) {

    defer close(done) // channel will be closed in the function exit phase

    fmt.Println("Inside goroutine:: myFunc()")

    fmt.Println(10 + <-ch) //<-- According to rule, control will be blocked here until 'ch' sends some data so that it will be received in our myFunc() go routine.

}

func main() {


    fmt.Println("Start Main method")

    // Creating a channel

    ch := make(chan int)

    done := make(chan struct{}) // signal channel


    go myFunc(ch, done) //<-- This go routine started in a new thread


    time.Sleep(2 * time.Second) //<--- introduced a Sleep of 2 seconds to ensure that myFunc() go routine executes before main thread

    ch <- 10

    <-done // waiting for function complete

    fmt.Println("End Main method")

}

或者使用雅罗斯瓦夫的建议。


查看完整回答
反对 回复 2022-09-19
?
BIG阳

TA贡献1859条经验 获得超6个赞

主戈鲁廷在戈鲁廷能够打印输出之前就已存在。下面是一个实现,它确保戈鲁廷在主戈鲁丁退出之前完成。myFuncmyFunc


package main


import (

    "fmt"

    "sync"

    "time"

)


func myFunc(ch chan int, wg *sync.WaitGroup) {

    defer wg.Done()

    fmt.Println("Inside goroutine:: myFunc()")

    fmt.Println(10 + <-ch) //<-- According to rule, control will be blocked here until 'ch' sends some data so that it will be received in our myFunc() go routine.

}

func main() {


    fmt.Println("Start Main method")

    // Creating a channel

    ch := make(chan int)

    wg := sync.WaitGroup{}

    wg.Add(1)

    go myFunc(ch, &wg) //<-- This go routine started in a new thread


    time.Sleep(2 * time.Second) //<--- introduced a Sleep of 2 seconds to ensure that myFunc() go routine executes before main thread

    ch <- 10

    wg.Wait()

    fmt.Println("End Main method")

}

此处的通道用于同步,其工作方式与文档中的说明相同。这并不意味着从代码中的这一点开始的代码将以相同的速度执行。这只意味着如果戈鲁廷没有从频道读取,主戈鲁廷将不会继续。并将等待主戈鲁丁将数据推送到通道。发生这种情况后,两个哥律特将继续独立执行。myFuncmyFunc


查看完整回答
反对 回复 2022-09-19
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

因为去太快了...https://play.golang.org/p/LNyDAA3mGYY

发送到频道调度程序后,速度不快...和程序存在。我为调度程序引入了一个额外的上下文切换器来显示效果。


查看完整回答
反对 回复 2022-09-19
?
长风秋雁

TA贡献1757条经验 获得超7个赞

是的,你是对的


我认为,这是因为主线程首先完成了它的执行,因此,所有其他goroutine也终止了。


如果您检查上述程序的执行情况。休眠状态是在主线程写入通道之前。现在即使哪个 goroutine() 将有 CPU 时间是完全任意的,但在上述情况下,如果休眠在逻辑之前。 将被阻止,因为 中没有数据mainexplicit sleepmyFuncch


在这里,我对上面的代码进行了轻微的更改,以便在将数据写入 Channel 后进行睡眠。它提供预期的输出,不使用 或 。mainwaitgroupquit channels


package main


import (

    "fmt"

    "time"

)


func myFunc(ch chan int) {

    fmt.Println("Inside goroutine:: myFunc()")

    fmt.Println(10 + <-ch) //<-- According to rule, control will be blocked here until 'ch' sends some data so that it will be received in our myFunc() go routine.

}

func main() {


    fmt.Println("Start Main method")

    // Creating a channel

    ch := make(chan int)


    go myFunc(ch) //<-- This go routine started in a new thread


   

    ch <- 10

    

    time.Sleep(2 * time.Second) //<--- introduced a Sleep of 2 seconds to ensure that myFunc() go routine executes before main thread



    fmt.Println("End Main method")

}


查看完整回答
反对 回复 2022-09-19
  • 4 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号