この投稿では、ゴルーチンとチャネルについて紹介します。これらは Go で最も便利な 2 つの構造です。これらを適切に使用すると、開発者は同時実行性を非常に柔軟に処理できます。これらはインタビューで最も一般的なトピックの 1 つです。
シンプルなプロデューサーコンシューマーパターンをgoに実装します。
これは最も単純な実装の 1 つです。しかし、このパターンは非常に一般的です。値を「生成」するスレッドと、値を「消費」する必要があるスレッドがあります。 golang では、スレッド間でこれらの値を渡す方法がチャネルです。
まず、整数用のチャネルを作成します。次に、プロデューサー関数とコンシューマー関数を実装するルーチンを作成します。
マルチスレッドの状況では、同期が問題になります。 Golang は、同期を実装する手段の 1 つとして WaitGroup を作成しました。これらは単にカウンターとして機能し、同期する必要があるスレッドはカウントが 0 になるまで待機します。制御スレッドは Done() 関数を使用してカウンターをデクリメントします。
この問題では、プロデューサーとコンシューマーの両方に WaitGroup を作成し、両方をカウント 1 に初期化します (Add() 関数を使用)。
メインスレッドはプロデューサー、コンシューマー、そしてプロデューサーを待機するインラインスレッドを起動し、その後コンシューマーが完了するのを待ちます。 プロデューサースレッドは通常通りデータの送信を開始します。完了すると、WaitGroup を使用して、チャネルへの送信が完了したことを通知します。インライン goroutine は、チャネルを閉じるプロデューサー WaitGroup を待機します。チャネルが閉じられないと、コンシューマはさらなるデータを待って永久にスリープ状態になり、プロセスは決して終了しません。 コンシューマーにデータがなくなると (チャネルが閉じられたため)、2 番目の WaitGroup に完了を通知します。 プロデューサーとコンシューマーのスレッドを起動したメインスレッドは、コンシューマーの WaitGroup が完了を許可するまで待機します。これにより、メインスレッドが途中で終了し、プロセス内のすべてのスレッドが強制終了されるのを防ぎます。 これは、生産者と消費者のパターンを実装する唯一の方法ではありません。 SIGTERM や SIGINT などのシグナルからの外部終了など、実稼働コードで対処する必要がある問題もいくつかあります。これは基本を示す簡単なデモンストレーションです。 他にどのように実装しますか?上記の実装には何が欠けていますか?コメントや他の実装へのリンクを以下に投稿してください。 ありがとう!この投稿とこのシリーズのすべての投稿のコードはここにあります
以上が生産者と消費者のパターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。