отличается от отмены и времени ожидания в контексте Голанга - PullRequest
2 голосов
/ 23 июня 2019

Я новичок в Голанге, и у меня возникает путаница в отношении WithCancel и WithTimeout, когда я изучаю контекстную часть Голанга.

Показать код.

package main

import (
    "context"
    "fmt"
    "time"
)

func someHandler() {
    //ctx, cancel := context.WithCancel(context.Background())
    ctx, cancel := context.WithTimeout(context.Background(),  2*time.Second)
    go doSth(ctx)

    time.Sleep(3 * time.Second)
    cancel()
}

func doSth(ctx context.Context) {
    var i = 1
    for {
        time.Sleep(1 * time.Second)
        select {
        case <-ctx.Done():
            fmt.Println("done")
            return
        default:
            fmt.Printf("work %d seconds: \n", i)
        }
        i++
    }
}

func main() {
    fmt.Println("start...")
    someHandler()
    fmt.Println("end.")
}

Результат:

// when use WithCancel
//
start...
work 1 seconds: 
work 2 seconds: 
end.

// when use WithTimeout
start...
work 1 seconds:
done
end.

Мой вопрос: почему он не печатает 'done', когда я использую withCancel, а withTimeout печатает его?

1 Ответ

1 голос
/ 23 июня 2019

" Понимание контекстного пакета в golang " из Parikshit Agnihotry упоминает:

context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)

Эта функция создаетновый контекст, полученный из родительского контекста, который передается.
Родитель может быть фоновым контекстом или контекстом, который был передан в функцию.

Возвращает производный контекст и функцию отмены.
Только функция, которая создает это, должна вызывать функцию отмены для отмены этого контекста.
Вы можете обойти функцию отмены, если хотите, но это настоятельно не рекомендуется.Это может привести к тому, что инициатор отмены не поймет, каким может быть последующее влияние отмены контекста.Из этого могут быть и другие контексты, которые могут привести к неожиданному поведению программы.Короче говоря, НИКОГДА не передавайте функцию отмены.

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))

context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc)

Эта функция возвращает производный контекст от своего родителя, который отменяется при превышении срока или вызывается функция отмены.

Например, вы можете создать контекст, который будет автоматически отменяться в определенное время в будущем, и передавать его в дочерних функциях.
Когда этот контекст отменяется из-за истечения срока,все функции, получившие контекст, получают уведомление о прекращении работы и возврате.

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))

context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc)

Эта функция аналогична context.WithDeadline.
Разница в том, что в качестве входных данных используется длительность времени вместо объекта времени .
Эта функция возвращает производный контекст, который отменяется при вызове функции отмены или продолжительности тайм-аута.превышено.

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))

почему не печатается "готово" при использовании с Cancel, но с помощью TimeTime делает

Возможно, потому что программа Go ужевыйдет, прежде чем программа успеет подтвердить "Готово".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...