>  기사  >  백엔드 개발  >  Go에서 지정된 시간 제한 이후 고루틴을 어떻게 정상적으로 취소할 수 있나요?

Go에서 지정된 시간 제한 이후 고루틴을 어떻게 정상적으로 취소할 수 있나요?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-19 19:25:03745검색

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() Goroutines 취소 신호를 보낸 다음 반환됩니다.

위 내용은 Go에서 지정된 시간 제한 이후 고루틴을 어떻게 정상적으로 취소할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.