平等なアクセスを備えたチャネル マルチプレクサ
この Go マルチプレクサは、複数のチャネルの出力を 1 つにマージすることを目的としており、各入力チャネルが出力チャンネルに対する同等の権利。ただし、提供されたテストでは予期しない結果が得られます。
問題の分析
重大な問題は、Mux 関数から生成されたゴルーチンにあります。各入力チャンネルを表すことを目的としたチャンネル パラメーター c は、ループの反復ごとに更新されます。これは、すべてのゴルーチンが、意図した個別のチャネルではなく、同じチャネルからプルすることになることを意味します。
解決策
この問題を解決するには、ゴルーチン作成ループを変更して次のパスを渡します。各ゴルーチンへの正しいチャネル:
for _, c := range channels { go func(c <-chan big.Int) { ... }(c) }
これを行うことで、各ゴルーチンは次の値を取得します。
同時実行の安全性の向上
出力チャネルへの平等なアクセスを保証することに加えて、同時実行の安全性を確保するために重要です。最初のコードは、int 変数 n を使用して入力チャネルの終了を追跡します。ただし、GOMAXPROCS が 1 より大きい場合、複数のゴルーチンが n に同時にアクセスする可能性があり、競合状態が発生する可能性があります。
より安全なアプローチは、ゴルーチンが相互に待機できるようにする sync.WaitGroup オブジェクトを使用することです。そして、n が安全に更新されることを保証します。 sync.WaitGroup を使用して修正されたコード:
import ( "math/big" "sync" ) // ... other code ... // The channel to output to. ch := make(chan big.Int, len(channels)) var wg sync.WaitGroup wg.Add(len(channels)) // ... other code ... // Close the channel when the pumping is finished. go func() { // Wait for everyone to be done. wg.Wait() // Close. close(ch) }()
これらの変更により、マルチプレクサは正しく安全に動作し、すべての入力チャネルが出力チャネルに平等にアクセスできるようになり、競合状態が回避されるようになりました。
以上がGo マルチプレクサーはどのようにして複数の入力チャネル間で公平かつ安全なアクセスを確保できるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。