ホームページ > バックエンド開発 > Golang > Go で指定された時間制限の後にゴルーチンを正常にキャンセルするにはどうすればよいですか?

Go で指定された時間制限の後にゴルーチンを正常にキャンセルするにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-11-19 19:25:03
オリジナル
818 人が閲覧しました

How Can I Gracefully Cancel Goroutines After a Specified Time Limit in Go?

時間制限後のゴルーチンのキャンセル

負荷テストのシナリオでは、ゴルーチンの実行時間を制御することが重要です。これを達成するための効果的なアプローチを次に示します。

Goroutines で HTTP リクエストを管理する次のコード スニペットを考えてみましょう:

func attack(cfg AttackConfig) {
    // some code ...

    var ar attackResponse
    ch := make(chan uint8, 8)

    go func() {
        time.Sleep(cfg.Duration * time.Second)
        ch <- CALL_TIME_RAN_OUT
    }()

    for {
        if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 {
            go httpPost(cfg, &ar, ch)
        }

        switch <-ch {
        // some other cases ...
        case CALL_TIME_RAN_OUT:
            fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration)
            return
        }
    }
}
ログイン後にコピー

ただし、httpPost() の Goroutines は、指定された cfg.Duration の後も実行され続けます。

この問題に対処するには、Go のコンテキスト パッケージを利用できます。 context.Context オブジェクトをゴルーチンに渡すことで、指定したタイムアウトに達したときにそれらのゴルーチンをキャンセルできます。

コンテキスト パッケージを使用したコードの改訂版は次のとおりです。

import (
    "context"
    "fmt"
    "golang.org/x/net/context"
    "time"
)

func attack(cfg AttackConfig) {
    // some code ...

    var ar attackResponse

    // Define a timeout context
    ctx, cancel := context.WithTimeout(context.Background(), cfg.Duration*time.Second)
    defer cancel()

    go func() {
        time.Sleep(cfg.Duration * time.Second)
        cancel()
    }()

    for {
        if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 {
            go httpPost(ctx, cfg, &ar)
        }

        select {
        // some other cases ...
        case <-ctx.Done():
            fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration)
            return
        }
    }
}

func httpPost(ctx context.Context, cfg AttackConfig, a *attackResponse) {
    // some code here to create HTTP client ...

    for {
        // some code to make HTTP call ...

        select {
        case <-ctx.Done():
            return
        default:
        }
    }
}
ログイン後にコピー

この変更により、指定された cfg.Duration の有効期限が切れると、ctx.Done() チャネルが閉じられ、httpPost() のキャンセルが通知されます。その後返されるゴルーチン。

以上がGo で指定された時間制限の後にゴルーチンを正常にキャンセルするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート