Как расписание распорядков работает с GOMAXPROCS? - PullRequest
0 голосов
/ 18 марта 2020

Меня так смущают горутины .

Вот код

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

func spinner(delay time.Duration) {
    for {
        for _, r := range `-\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
        }
    }
}

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

Это простой учебный код goroutine , который при использовании goroutine для показывает анимацию ASCII при вычислении * Фибоначчи 1013 *.

Когда я устанавливаю GOMAXPROCS в 1, я думаю, что будет только один поток для выполнения процедуры, и функция Фибоначчи не имеет смысла уступать анимации. Но эта демонстрация все еще работает. Он показывает анимацию во время расчета.

Как Go делает это без переключения рутин?

1 Ответ

2 голосов
/ 18 марта 2020

Среди прочего: компилятор вставляет потенциальные точки переключения при каждом вызове функции, поэтому каждый рекурсивный вызов fib(...) может уступать программе «spinner».

Если вы попытаетесь реализовать fib без вызова функции например:

// note : this is a truly horrific way to compute the Fibonacci sequence,
//        don't do this at home
// simulate the "compute Fibonacci recursively" algorithm,
// but without any function call
func fib(n int) int {
    var res = 0

    var stack []int
    stack = append(stack, n)

    for len(stack) > 0 {
        // pop :
        n = stack[len(stack)-1]
        stack = stack[0 : len(stack)-1]

        if n < 2 {
            res += n
            continue
        }

        // else : push 'n-1' and 'n-2' on the stack
        stack = append(stack, n-1, n-2)
    }

    return res
}

https://play.golang.org/p/pdoAaBwyscr

вы должны увидеть, что ваш счетчик застрял

...