import "context"
!
コンテキストパッケージのソースコードを表示します!
コンテキストを使用するサーバーのサンプルコードを参照してください。
コンテキストに関するgolangドキュメントを表示してください!
サンドイッチを作る必要があるとすると、トマト、パン、ハムを購入するために3人を手配します。ハムの買い手は、スーパーに着いたときにハムがないことに気づいたので、スーパーの店員にその場でハムを作ってもらいました。パンとトマトを買う人は、それぞれパン屋とトマトショップに行く途中です。
この時、いきなりハムを食べないことにしたのですが、資源を無駄にしないためには、ハムメーカーがハムを作るのをやめ、スーパーに行く人がすぐにスーパーに行くのをやめ、人がハムを待つことはすぐにハムを待つことをやめます。
カスタム機能sleepAndTalk()
-
func sleepAndTalk(ctx context.Context, d time.Duration, msg string) {
select {
case <- time.After(d)
fmt.Println(msg)
case <- ctx.Done()
log.Print(ctx.Err())
}
}
キャンセル-
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
go func () {
s := bufio.NewScanner(os.Stdin)
s.Scan()
cancel()
}()
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
go run *.go
上記のコードを実行することにより、そうでない場合はStdin
、5秒後に出力しますHello
。5秒以内であればStdin
、すぐcancel
に実行されsleepAndTalk()
ます。
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
go func () {
time.Sleep(time.Second)
cancel()
}()
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
Cancel()
1秒後。上記のコードは-と同等です
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
time.AfterFunc(time.Second, cancel)
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
または-
func main() {
ctx := Context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Second)
cancel() // release resources for timer
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
キャンセルを処理するメソッド-
Background()
WithCancel()
WithTimeout()
WithDeadline()
チャネルとオプションを使用する
func main() {
stop := make(chan bool)
go func() {
for {
select {
case <- stop: // 在channel收到值后输出stop并返回
fmt.Println("stop!")
return
default: // 在channel收到任何bool之前一直会跑default
fmt.Println("running...")
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
stop <- true
time.Sleep(5 * time.Second)
}
チャネルと選択は、複雑なスレッドツリーを処理できません。
コンテキストは大丈夫ですか?
func main() {
// Background() is the root Context
// WithCancel() add a new Context node
ctx, cancel := context.WithCancel(context.Background())
go func() {
for {
select {
case <- ctx.Done(): // Done()在引用cancel()之后打开channel
fmt.Println("stop!")
return
default: // 在channel收到任何bool之前一直会跑default
fmt.Println("running...")
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
cancel()
time.Sleep(5 * time.Second)
}
複数のスレッドの例-
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx, node1)
go worker(ctx, node2)
go worker(ctx, node3)
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
cancel()
time.Sleep(5 * time.Second)
}
func worker(ctx context.Context, name string) {
go func() {
for {
select {
case <- ctx.Done(): // Done()在引用cancel()之后打开channel
fmt.Println(name, "stop!")
return
default: // 在channel收到任何bool之前一直会跑default
fmt.Println(name, "running...")
time.Sleep(1 * time.Second)
}
}
}
}