如果在第一次迭代和第二次迭代之间存在小的时刻

时间:2014-07-26 18:00:06

标签: go

在下面的代码中,迭代运行两次 是否有可能在第一次迭代和第二次迭代之间运行“test2< - true”? 我的意思是,当第一次迭代结束并且第二次迭代没有开始时,是否有变化发送到“test2”?

package main

import "log"
import "time"

func main() {
    test := make(chan bool, 1)
    test2 := make(chan bool, 1)

    go func() {
        for {
            select {
            case <-test:
                log.Println("test")
            case <-test2:
                log.Println("test2")
            }
        }
    }()

    test <- true
    time.Sleep(1)
    test2 <- true
    time.Sleep(1)
}

2 个答案:

答案 0 :(得分:4)

是。由于您的频道已缓冲并且可以容纳1个值。主执行流程可以继续,而不会让您的匿名goroutine读取您发送到test频道的值,并且它可以在goroutine唤醒之前在test2频道上发送值并读取{上的值{1}}频道。

这种情况不太可能发生,因为你有一个time.Sleep()调用那里通常会给goroutine执行时间,但是没有人知道在你的机器非常繁忙的角落里会发生什么在(非)幸运时间暂停权力或其他你没想过的事情。

如果您的test频道未缓冲,test语句会阻止,直到您的goroutine收到该值,并且goroutine至少不可能从test <- true收到从test2频道收到任何内容。

答案 1 :(得分:3)

添加到nos&#39; answer,您可以模拟这种情况(其中&#34; test2 <- true&#34;在第一次迭代和第二次迭代之间的时刻运行&#34;)通过制作很容易您的第一个留言接收(case <- test)等一秒钟。

case <-test:
    log.Println("test")
    time.Sleep(1 * time.Second)

当匿名goroutine唤醒时,main()已经将其两条消息发送到两个缓冲通道(缓冲区意味着非blokcing 一条消息),并退出。登记/> 如果main()退出,其他所有内容,包括忙着睡觉的goroutine,都会停止。

参见 play.golang.org :输出为:

2009/11/10 23:00:00 test

您没有时间看test2


为了确保您的goroutine可以处理两个消息,您需要:

  • main()等待所说的goroutine完成。这就是sync package发挥作用的地方,使用(例如,这不是唯一的解决方案)WaitGroup指令。

    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        // Decrement the counter when the goroutine completes.
        defer wg.Done()
        ...
    }
    ... // end of main():
    // Wait for goroutine to complete.
    wg.Wait()
    
  • goroutine在某个时间实际退出(而不是永远停留在for循环中)。请参阅&#34; In Go, does a break statement break from a switch/select?&#34;

    loop:                                  <==========
    for {
        select {
        case <-test:
            log.Println("test")
            time.Sleep(1 * time.Second)
        case <-test2:
            log.Println("test2")
            break loop                     <==========
        }
    }
    

请参阅 play.golang.org :在test2之后goroutine正在休眠时发送消息test1,但main()将等待({{1} }},并且goroutine将有机会在一秒钟之后阅读并打印wg.Wait()

输出结果为:

test2
相关问题