Лучшая замена именованных мьютексов для синхронизированного доступа к каждому ресурсу

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] одновременно), поэтому я использовал приведенный выше код. Какая лучшая альтернатива именованным мьютексам в этом сценарии?


person Xaqron    schedule 20.04.2011    source источник


Ответы (2)


Если это все в одном процессе, тогда нет необходимости в именованных мьютексах. Просто создайте список или массив из 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 объектов в начале вашей программы и держать их под рукой. Таким образом, в цикле все, что вам нужно сделать, это _5 _-- нет необходимости создавать объект каждый раз в цикле.

person Jim Mischel    schedule 20.04.2011
comment
Фактически ресурсы не имеют индексов. У них уникальные имена, поэтому есть resource[key], а не resource(i), тогда какой тип подходит для использования в качестве блокировки? - person Xaqron; 21.04.2011
comment
Я бы предложил использовать опубликованное мною решение с List<object> для замков. Итак, чтобы использовать resource[key], вы блокируете LockObjects[key]. Если key не является последовательным целым числом, создайте Dictionary<keyType, object> для блокировок. Пока существует взаимно однозначная связь между объектами блокировки и ресурсами, все должно быть в порядке. - person Jim Mischel; 21.04.2011

Предполагая, что ресурсы являются экземплярами ссылочных классов, просто заблокируйте каждый ресурс.

var r = resource(i);
lock (r)
{
    // synchronized access to resource(i)
}
person Marcelo Cantos    schedule 20.04.2011
comment
К сожалению, ресурсы - это Lazy объекты, и я предпочитаю не будить их без надобности, но идея творческая. - person Xaqron; 21.04.2011