Golang は、同時実行性が高く効率的なプログラミングを構築するために設計された言語で、プログラムの実行効率とパフォーマンスを大幅に向上させる便利で効率的な goroutine メカニズムを提供します。ただし、Goroutine を使用する場合、Goroutine の実行を停止する方法など、注意しなければならない点がいくつかあります。以下では、Goroutine を停止する方法に焦点を当てます。
Goroutine を停止する方法を理解する前に、まず goroutine の基本的な知識を理解する必要があります。 Goroutine は Golang 言語での軽量スレッドの実装であり、1 つ以上のスレッドで実行できます。これは Go ランタイム システムによって管理され、独立した軽量の実行ユニットです。従来のスレッドとは異なり、ゴルーチンは実行時に Go ランタイム システムによって自動的にスケジュールされ、そのスケジューリング モデルも非常に効率的で、高い同時実行性を適切にサポートするだけでなく、マルチコア CPU を最大限に活用できます。
Go 言語では、次の 2 つの一般的な方法でゴルーチンを作成できます。
go func() { //goroutine运行的代码 }()
func myFunc() { //goroutine运行的代码 } go myFunc()
Goroutine には Provide がないため、Goroutine を停止することはより複雑な問題になります。終了および一時停止するための明示的なメソッド。これは、Go 言語の設計目標の 1 つは実行中にゴルーチンがブロックされないようにすることであるため、ゴルーチンを停止するには特別なテクニックが必要になるからです。
Go 言語では、Goroutine を停止するには次の 4 つの方法があります:
チャネルを使用するのが、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) }
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) }
共有変数を通じて 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) }
ランタイムパッケージの使い方は少し面倒で、ゴルーチンで実行するコードでは定期的にグローバル変数をチェックする必要があり、 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 サイトの他の関連記事を参照してください。