web-dev-qa-db-ja.com

マルチスレッド環境でのエラー処理戦略

TL; DR他のユーザーが使用することを目的としたマルチスレッドコードで使用するエラー生成と処理の戦略は何ですか?なぜそれらを使用するのですか?該当する場合は、それが役立つプログラミングパラダイムを示します。私は命令型の並行環境にもっと興味がありますが、一般的にはどれも役に立ちます。

現在、pet/C++ 11学習プロジェクトですが、後で私の作業で内部的に使用される可能性がある、小さな並行処理ライブラリを作成しています。ドメインに関しては、DSPとメディアストリーミングの領域にありますが、これはゲームエンジンで使用されるため、かなり強力なエラー処理が必要です。

現時点での私の大きなブロックは、並列コードとデータ構造に頭を悩ませているのではなく、エラー処理とレポートを行う方法です。大規模システムでの主な経験はゲームですが、通常はライブラリを使用しており、設計はしていません。これは私の知識のかなり大きなギャップであるため、さまざまな戦略と、それらがさまざまな状況でどのように使用されるかを探しています。

私の最大の関心事は、プログラムが回復できる場合は回復するように戦略を採用することです。回復する場合は、何らかのメカニズムによって何が起こったかをユーザーに通知する方法が必要です。すでにいくつかのデータ構造がありますが、それらは回復できますが、たとえばデストラクタが失敗した場合にメモリがリークする可能性があります。

いくつかのアプローチ:

  • ライブラリ内から安全に回復できる例外を処理しますが、致命的な例外をライブラリのユーザーに伝えて、オブジェクトが未定義の状態にあることを示します。これはシングルスレッド環境での私の推奨アプローチですが、このアプローチは不良状態を他のスレッドに伝えません。
  • データ構造を回復不可能な状態にする例外が発生した場合は、データ構造を破棄し、フラグを設定してそのデータ構造に対するこれ以上の操作をブロックし、一般的な例外をエンドユーザーに通知します。これは、ロックのないアルゴリズムでは困難です。
  • 並列計算を通じてエラー状態を転送します。カーンプロセスネットワークおよびその他の高レベルの同時実行モデルに適しています。高レベルモデルをサポートするプリミティブが失敗した場合、それほど役に立ちません。
  • 例外の原因となったスレッド/タスクを終了します。スレッドローカルデータ/計算には適していますが、共有データの解決策にはなりません。

ちょうどメモとして、私は良いライブラリがおそらく上にリストされたもの以上のものの混合を使用することを知っています。十分に大きなシステムの場合、どの戦略が適切かを知る経験はありません。

5
BlamKiwi

私の2セント。

まず、ライブラリで見たほとんどの非同期モデルは、私を苛立たせる傾向があります。誰もが独自の少し異なるブランドの非同期を持っているようで、それらのインターフェースの多くは良くありません。そのため、私はすべてを同期させるライブラリを好む傾向があります。コールバックはそれでも良いことに注意してください。ただし、すべてのロジックを1つのスレッドに保持します。アプリケーションプログラマーは、ライブラリが実行しようとしているタスクとは別にスレッド化について考えたいことがよくあります。

第二に、非同期コード専用の小さなライブラリーは、それが唯一の焦点である限り、非常に良いことです。私がC#で見て気に入ったパターンは、さまざまなスレッドでアクションをチェーン化することですが、流れるようなインターフェイスでほぼ単一のスレッド方式で記述します。 (新しいキーワードawaitは多少同じ行に沿っています。)これが発生する一般的な場所の1つは、UIスレッドへのディスパッチです。次に、catchブロックのように、最後に例外を処理する方法を提供します。したがって、たとえば次のようなものでしょう。

...
int expensiveResult=-1;
YourThreadLibrary
  .Background(()=>expensiveResult=DoLongRunningTaskToCreate())
  .UI(()=>UpdateUI(expensiveResult))
  .Exception(ex=>LogIt(ex));

例外はC#を使用する方法であり、GCがあるため、状況は異なる場合があります。しかし、そのパターンはまだ意味があるかもしれません。

これは単純すぎるように見えるかもしれませんが、これらは、多くの問題を処理するのに十分一般的であると私が見たツールです。良いことに、このような流暢なインターフェイスは、適切に記述されていれば、間違いなく拡張機能を利用できるため、.ParallelFailOnAny(params Action [])などを追加できます。

2
J Trana