私はユーザーがファイルをアップロードし、処理のためにキューに入れることができるアプリを書いています。私のアプローチは、アップロードされたファイルを処理するためのゴルーチンを作成し、チャンネルを使って新しいファイルが処理できる状態になったことを知らせることです。ワーカーのゴルーチンのアイテムをキューに入れる正しい方法は?
は、基本的には、処理ゴルーチンがこれを行います。これは非であることを
select {
case signalChan <- true:
default:
}
注:
for {
while itemForProcessing() {
processNextItem()
}
select {
case <-signalChan:
case <-stopChan:
return
}
}
新しいアイテムが処理のために準備ができていることを知らせるためのコードは次のようになりますチャンネルで送信をブロックします。
は、三つの可能なシナリオがある:
- 処理ゴルーチンは—
select{}
ブロックにある最初の場合は実行され、次の項目が - 処理された処理ゴルーチンは、次の項目があろう
processNextItem()
—を実行しています一度処理されたループの状態はtrue
- となりますので、ループを終了しましたが、まだ完了していません。
processNextItem()
select{}
ブロックを入力しました
最後のシナリオでは問題が発生します。ノンブロッキング送信はチャネル上で何も送信しません。何か他のことが起こるまで、ゴルーチンはselect{}
ブロックで待機します。
どうすればこの問題を回避できますか?処理中のゴルーチンがprocessNextItem()
を実行している可能性があるため、ブロッキング送信を使用することはできません。これにより、非常に長い時間ブロックが送信されます。
チャネルにチャネルを使用し、失われた信号を避けるためには、更新可能フラグとして動作します - アプリは読むことができますどのような何かがあるとのシグナル伝達します。私は事を単純化する可能性があると思う - ちょうどチャネルを介して治療するために新しいオブジェクトを渡す。これにより、簡単な並列処理、競合状態の保護、単純化といういくつかの問題が解決されます。 –