ホームページ >バックエンド開発 >Golang >Golang で goroutine を停止する方法 (4 つの方法)

Golang で goroutine を停止する方法 (4 つの方法)

PHPz
PHPzオリジナル
2023-04-11 10:42:061371ブラウズ

Golang は、同時実行性が高く効率的なプログラミングを構築するために設計された言語で、プログラムの実行効率とパフォーマンスを大幅に向上させる便利で効率的な goroutine メカニズムを提供します。ただし、Goroutine を使用する場合、Goroutine の実行を停止する方法など、注意しなければならない点がいくつかあります。以下では、Goroutine を停止する方法に焦点を当てます。

Goroutine の基本

Goroutine を停止する方法を理解する前に、まず goroutine の基本的な知識を理解する必要があります。 Goroutine は Golang 言語での軽量スレッドの実装であり、1 つ以上のスレッドで実行できます。これは Go ランタイム システムによって管理され、独立した軽量の実行ユニットです。従来のスレッドとは異なり、ゴルーチンは実行時に Go ランタイム システムによって自動的にスケジュールされ、そのスケジューリング モデルも非常に効率的で、高い同時実行性を適切にサポートするだけでなく、マルチコア CPU を最大限に活用できます。

ゴルーチンの作成方法

Go 言語では、次の 2 つの一般的な方法でゴルーチンを作成できます。

  1. go キーワードを使用する
go func() {
    //goroutine运行的代码
}()
  1. go キーワードと関数名を使用します
func myFunc() {
    //goroutine运行的代码
}

go myFunc()

Goroutine を停止する方法

Goroutine には Provide がないため、Goroutine を停止することはより複雑な問題になります。終了および一時停止するための明示的なメソッド。これは、Go 言語の設計目標の 1 つは実行中にゴルーチンがブロックされないようにすることであるため、ゴルーチンを停止するには特別なテクニックが必要になるからです。

Go 言語では、Goroutine を停止するには次の 4 つの方法があります:

1. チャネルを使用する

チャネルを使用するのが、Goroutine を停止する最も簡単かつ安全な方法です。 bool 型のチャネルを作成し、ゴルーチンを停止する必要がある場合は、このチャネルにシグナルを送信します。シグナルを受信した後、ゴルーチンは正常に終了します。

func worker(stopChan chan bool) {
    for {
        select {
        case <-stopChan:
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    stopChan := make(chan bool)
    go worker(stopChan)
    time.Sleep(3 * time.Second)
    stopChan <- true
    time.Sleep(time.Second)
}
2. context の使用

Go1.7 では、context パッケージが標準ライブラリに追加され、ゴルーチンを一時停止およびキャンセルする新しい方法が提供されました。各ゴルーチンで Context パラメータを渡し、ゴルーチンを停止する必要があるときにこの Context 変数に対してキャンセル操作を実行できます。

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    go worker(ctx)
    time.Sleep(3 * time.Second)
    cancel()
    time.Sleep(time.Second)
}
3. Mutex と WaitGroup を使用する

共有変数を通じて goroutine の停止を制御するには、このメソッドでは同期パッケージで Mutex と WaitGroup を使用する必要があります。 Mutex は共有変数の読み取りと書き込みを保護するために使用され、WaitGroup はすべてのゴルーチンが完了するのを待つために使用されます。

var wg sync.WaitGroup
var stop bool
var mutex sync.Mutex

func worker() {
    defer wg.Done()
    for {
        mutex.Lock()
        if stop {
            mutex.Unlock()
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        mutex.Unlock()
        time.Sleep(time.Second)
    }
}

func main() {
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go worker()
    }
    time.Sleep(3 * time.Second)
    mutex.Lock()
    stop = true
    mutex.Unlock()
    wg.Wait()
    time.Sleep(time.Second)
}
4. ランタイムパッケージの使い方

ランタイムパッケージの使い方は少し面倒で、ゴルーチンで実行するコードでは定期的にグローバル変数をチェックする必要があり、 goroutine を停止する必要がある場合は、ランタイム パッケージの関数を使用して強制終了します。

var stop bool

func worker() {
    for {
        if stop {
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        time.Sleep(time.Second)
    }
}

func main() {
    go worker()
    time.Sleep(3 * time.Second)
    stop = true
    time.Sleep(time.Second)
    runtime.Goexit() //退出当前运行的goroutine
}

まとめ

Goroutineを使用するとプログラムの同時実行性能が大幅に向上しますが、Goroutineの動作を制御することも非常に重要であり、Goroutineをいかに適切に停止させるかが課題となっています。 。上記 4 つの方法にはそれぞれ独自の利点と適用可能なシナリオがあり、特定の状況に応じて最適な方法を選択する必要があります。

以上がGolang で goroutine を停止する方法 (4 つの方法)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。