【发布时间】: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