【问题标题】:C# .net HDF5 Nunit issue?C# .net HDF5 Nunit 问题?
【发布时间】:2017-04-05 21:23:48
【问题描述】:

我们正在将 HDF5 库集成到我们的 .NET 应用程序中。

由于 HDF5 库不是线程安全的,我们使用 lock() 对其进行了封装。我们程序的一个线程处理一个独占的 .h5 文件。

一些计算是并行完成的。对于我们使用的并行部分:

  • 线程
  • Parallel.foreach()

来自:

  • System.Threading
  • System.Threading.Tasks。

当我们使用 NUnit v3.2.1 使用线程、parallel.foreach 执行一些单元测试时,一切都在工作文件 execpt,在一个 .h5 文件中每个实例都有一个实例,最终值(因为它们被读取和写入多次)在我们的 .h5 文件中不正确(否则它们是正确的)。

我们怀疑 HDF5 库在所有四个(HDF5、NUnit、Threads、Parallel.foreach)的组合中存在问题。我们对正在发生的事情没有明确的线索。

工具:Visual Studio 2015 Pro、NUIt 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);
        }
    }

【问题讨论】:

  • 如果使用锁,使用Parallel 有什么意义?此外,锁定不会通过魔法使某些东西成为线程安全的。 AcessLock 是静态字段还是实例字段?还有人用手柄吗?
  • 不会使用锁定来保护这样的资源。我会使用 ActionBlock](msdn.microsoft.com/en-us/library/hh194684(v=vs.110).aspx) 将消息发布到使用单个任务执行修改的块。
  • 并行用于我们的不同计算(因为我们同时计算多个数据)。 AccessLock 是单例(.h5 IO 方法所在的位置)内的实例字段(对象)。我会检查 ActionBlock。谢谢!
  • 就像对原始帖子的评论一样。并行用于同时计算多个输入,而锁用于一次使用一个线程使用 HDF5 库。我们同意,使用锁不会神奇地使某些东西成为线程安全的,但这可以避免一些问题。

标签: c# .net multithreading nunit hdf5


【解决方案1】:

到目前为止,我通过在每次编辑 HDF5 文件时执行以下操作解决了保持相同配置(NUnit、线程和 Parallel.foreach)的问题:

  1. 打开文件
  2. 执行 IO 操作
  3. 关闭文件
  4. 以读/写模式重新打开文件 (H5F.OpenMode.ACC_RDWR)
  5. 关闭文件

通过在我们的 HDF5 助手单例中使用锁来保护每个操作。这是因为一个线程一次处理一个 .h5 文件。

当您关闭 .h5 文件时,HDF5 库似乎会执行异步操作,因为在此步骤中,数据被推送到文件中。

文档并不清楚。

我从这个帖子中得到了这个想法: HDF5 Example code

关于 H5F 的 HDF5 文档。关闭: http://hdf5.net/api/M_HDF5DotNet_H5F_close_1_4829088c.aspx

【讨论】:

    【解决方案2】:

    问题现在解决了。

    我们的一个操作忘记从 HDF5 文件中关闭数据集元素,导致 H5F.Close 无效。

    症状:

    • 库仍在使用文件
    • 新数据未刷新到文件中

    解决方案:

    • 检查 HDF5 库中每一个使用后必须关闭的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 2013-06-09
      • 2010-12-16
      • 2016-05-11
      • 2017-03-14
      • 2016-01-12
      相关资源
      最近更新 更多