Why my goroutine stopped after a few moments running?

Issue

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(1)
    go spinner()
    const n = 45
    fibN := fib(n)
    fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}

func spinner() {
    for {
        for _ = range `-\|/` {
        }
    }
}

func fib(x int) int {
    fmt.Println(x)
    if x < 2 {
        return x
    }
    return fib(x-1) + fib(x-2)
}

After a few seconds, it stopped printing x in fib anymore. I deliberately use 1 processor to understand why it stops. Is the scheduler stuck and not rescheduling the goroutine running the fib anymore?

Solution

Is the scheduler stuck and not rescheduling the goroutine running the fib anymore?

Short answer: yes.

Longer answer: you aren’t guaranteed that this will happen, even with just one CPU. The system could do an occasional reschedule on its own. It’s just that the implementation on which you are testing this, doesn’t.

As JimB notes in a comment, the kind of hard-spin-loop you have in spinner is … unfriendly, at best. It should contain some method of releasing computing resources, such as spinning with time.After or time.NewTicker, or at the very least, call runtime.Gosched(). I imagine your original spinner was something like this, only without the time.NewTicker:

func spinner() {
    t := time.NewTicker(50 * time.Millisecond)
    for {
        for _, c := range `-\|/` {
            fmt.Print(string(c), "\b")
            <-t.C
        }
    }
}

With the ticker in place, the spinner spins pretty fast, but the program completes (despite the non-caching fib). Of course a smarter fib helps rather more:

var fibcache = map[int]int64{}

func fib(x int) int64 {
    if x < 2 {
        return int64(x)
    }
    r, ok := fibcache[x]
    if !ok {
        r = fib(x-1) + fib(x-2)
        fibcache[x] = r
    }
    return r
}

(I changed the return type to int64 for what I hope are obvious reasons.) Now we can find Fibonacci(90) = 2880067194370816120 in 0.00 seconds (rounded).

Answered By – torek

Answer Checked By – Timothy Miller (GoLangFix Admin)

Leave a Reply

Your email address will not be published.