对于每个资源的同步访问,最好替换命名互斥锁
本文关键字:替换 资源 于每个 同步 访问 | 更新日期: 2023-09-27 17:52:40
for (int i = 0; i < 100; i++)
{
// If current thread needs resource(i) then
Mutex mutex = new Mutex(false, "Mutex" + i.ToString());
mutex.WaitOne();
// synchronized access to resource(i)
mutex.ReleaseMutex();
}
我们有100个资源,每个资源应该由单个线程并发访问(同时访问资源[2]和资源[5]是可以的),所以我使用了上面的代码。在这种情况下,命名互斥体的最佳替代方案是什么?
如果这些都在一个进程中,那么根本不需要命名互斥锁。只需创建一个包含N个对象的列表或数组,并使用lock
。
const int NumLocks = 100;
List<object> LockObjects = new List<object>(NumLocks);
// to initialize
for (int i = 0; i < NumLocks; ++i)
{
LockObjects.Add(new object());
}
// and your loop
for (int i = 0; i < NumLocks; ++i)
{
// if current thread needs lock[i] then
lock(LockObjects[i])
{
// do whatever you need to do
// and then release the lock
}
}
或者,您可以锁定单个资源对象。如果它们真的是物体。我发现使用单独的锁对象更容易理解和维护,因为"资源"可能是一个方法或一组对象。锁对象是一个抽象,对我来说,它有助于理解。
如果多个进程需要这个,那么除了使用Mutex
之外,我没有看到一个好的解决方案。但是,我建议在程序开始时创建这些Mutex
对象的列表并保留它们。这样,在循环中您所要做的就是WaitOne
—不需要在循环中每次都创建对象。
假设资源是引用类的实例,只需锁定每个资源。
var r = resource(i);
lock (r)
{
// synchronized access to resource(i)
}