douyi8732 2012-10-14 17:48
浏览 28
已采纳

select的奇怪行为(不允许其他goroutine运行)

I'm trying to write SDL app in go using https://github.com/klkblake/Go-SDL.
I created timer to call draw function on it:

render_timer := time.NewTicker(time.Second / 60)

Somewhere in event loop:

for running == true {
    [...]
    [process sdl events]
    [...]
    select {
    case <-render_timer.C:
        call_my_draw_function()
    default:
        some_default_actions()
    }
    [...]
}

If I run program after compiling this code nothing is drawn on screen. But if I place just:

fmt.Println("default")

in the default branch of select -- the code begin to work as I want it to(draws something in window); and if i remove println it again don't draw anything.
What am I doing wrong? Why is there such behaviour of select ?


Hm... Simplest testcase is:

package main

import (
"fmt"
"time"
)

func main() {

    rt := time.NewTicker(time.Second / 60)
    for {
        select {
        case <-rt.C:
            fmt.Println("time")
        default:
        }
    time.Sleep(1) // without this line 'case <-rt.C' is never executed
    }
}
  • 写回答

2条回答 默认 最新

  • dousi5501 2012-10-14 18:51
    关注

    See golang: goroute with select doesn't stop unless I added a fmt.Print()

    Long story short, because of the default case, and because your GOMAXPROCS is probably set to 1 (the default value), it never schedules the goroutine to do its work. There are many options to fix this, depending on your needs (a sleep in default, a time.After() channel in the select instead of the default, a call to runtime.Gosched(), etc.).

    Adding the fmt.Print makes it work because - my guess, not sure - it involves io and internally causes a Gosched() (that or something like Phlip's answer in the related question, I just read it).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?