对于每个资源的同步访问,最好替换命名互斥锁

本文关键字:替换 资源 于每个 同步 访问 | 更新日期: 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)
}