2016-11-22 16 views
0

私たちは、.NETアプリケーションにHDF5ライブラリを統合しています。C#.net HDF5 Nunitの問題?

HDF5ライブラリはスレッドセーフではないため、lock()を使用してHDF5ライブラリをカプセル化しました。私たちのプログラムの1つのスレッドは、単一の排他的な.h5ファイルで動作します。

いくつかの計算は並行して行われます。平行部のために我々が使用:

  • System.Threading.TasksをSystem.Threading

    • :から

      • スレッド
      • Parallel.foreachを()

    NUnit v3.2.1でスレッド、parallel.foreachを使っていくつかの単体テストを実行すると、すべてが1つの単一の.h5ファイルに1つのインスタンスとして実行されます。私たちの.h5ファイルの中にある複数回の読み書きは正しいものではありません。

    HDF5ライブラリには、HDF5、NUnit、Threads、Parallel.foreachの4つの組み合わせの問題があると考えられています。我々は何が起こっているのか分かりません。

    ツール:Visual Studio 2015 Pro、NUNit v3.2.1およびNUnit3TestAdapter v3.5.1。

    提案がありますか?

    ありがとうございます。ここで

    は、我々はファイル内のいくつかのデータを書き込む方法のサンプルです:

    public void SetGroupAttribute(H5LocId hdf5Handle, string location, string attribute, int value) 
        { 
         lock (AccessLock) 
         { 
          // Retrieve the attribute to read 
          var attributeId = GetAttribute(hdf5Handle, location, attribute); 
    
          H5GroupId rootId = null; 
          if (attributeId != null) 
          { 
           // Remove the old attribute 
           rootId = H5G.open(hdf5Handle, location); 
           H5A.Delete(rootId, attribute); 
           H5G.close(rootId); 
          } 
    
          // Create and set the new attribute value 
          H5DataSpaceId spaceId = H5S.create(H5S.H5SClass.SCALAR); 
          var attributeType = H5T.copy(H5T.H5Type.NATIVE_INT); 
    
          rootId = H5G.open(hdf5Handle, location); 
          attributeId = H5A.create(rootId, attribute, attributeType, spaceId); 
          H5G.close(rootId); 
    
          // Set the attribute value 
          int[] dims = new int[1]; 
          dims[0] = value; 
          H5A.write<int>(attributeId, attributeType, new H5Array<int>(dims)); 
          H5A.close(attributeId); 
         } 
        } 
    
  • +0

    ロックを使用する場合、「並列」を使用するポイントは何ですか?また、ロックでは魔法によってスレッドセーフなものにはなりません。 'AcessLock'は静的なフィールドかインスタンスフィールドですか?他の誰かがハンドルを使用していますか? –

    +0

    I *は、そのようなリソースを保護するためにロックを使用しません。私はActionBlock ](https://msdn.microsoft.com/en-us/library/hh194684(v = vs.110).aspx)を使用して、単一のタスクを使用して変更を実行するブロックにメッセージを投稿します。 –

    +0

    Parallelは異なる計算に使用されます(複数のデータを同時に計算する場合)。 AccessLockは、シングルトン(.h5 IOメソッドがある)内のインスタンスフィールド(オブジェクト)です。私はActionBlockをチェックします。ありがとう! – Fabi1

    答えて

    0

    これまでのところ私は、次を毎回行うことによって、同じ構成(NUnitの、スレッドとParallel.foreachを)維持する問題を解決しました私はHDF5ファイルを編集:ファイルを閉じます

    1. ファイルを開く
    2. ドIO操作

    各操作は、当社のHDF5ヘルパーシングルトン内のロックを使用して保護されたファイルを閉じて、読み取り/書き込みモード(H5F.OpenMode.ACC_RDWR)でファイルを開きます。これは、一度に1つのスレッドが1つの.h5ファイルを処理しているときに機能します。

    この手順では、データがファイル内にプッシュされるため、HDF5ライブラリは.h5ファイルを閉じるときに非同期操作を行うようです。

    ドキュメントについては、明確ではありません。

    私はこのスレッドからこのアイデアをとっている:H5F.Closeについて HDF5 Example code

    HDF5ドキュメンテーション: http://hdf5.net/api/M_HDF5DotNet_H5F_close_1_4829088c.aspx

    0

    問題が解決されました。

    私たちの操作の1つは、HDF5ファイルからデータセット要素を閉じるのを忘れてしまったため、H5F.Closeを無効にすることでした。

    症状:

    • ファイルがまだライブラリで使用されては
    • 新しいデータがファイルにフラッシュされません

    ソリューション:

    • チェック一つ一つのオブジェクトからクローズしなければならないHDF5ライブラリは、一度使用していたものです。