Лучший способ обнаружить взаимные блокировки (IMO) - создать тестовую программу, которая вызывает все функции в случайном порядке примерно в 30 различных потоках 10000 раз.
Если вы зашли в тупик, вы можете использовать окно «Параллельные стеки» VS2010. Отладка-> Windows-> Параллельные стеки
Это окно покажет вам все стеки, чтобы вы могли найти методы, которые являются взаимоблокирующими.
Простая стратегия, которую я использую для написания потоковобезопасных объектов:
Потокобезопасный объект должен быть безопасным при вызове его открытых методов, поэтому вы не получите взаимоблокировки при его использовании.
Итак, идея состоит в том, чтобы просто заблокировать все открытые методы, которые обращаются к данным объекта.
Кроме того, вам нужно убедиться, что в коде класса вы никогда не вызываете публичный метод. Если вам нужно использовать один из открытых методов, сделайте этот метод закрытым и оберните закрытый метод открытым методом, который блокирует и затем вызывает его.
Если вы хотите улучшить детализацию блокировки, вы можете просто создать объекты для каждой детали, которая имеет свою собственную блокировку, и заблокировать ее, как я и предлагал. Затем используйте инкапсуляцию для объединения этих классов в один класс.
Пример:
class Blah {
MyData data;
Lock lock;
public:
DataItem GetData(int index)
{
ReadLock read(lock);
return LocalGetData(index);
}
DataItem FindData(string key)
{
ReadLock read(lock);
DataItem item;
//find the item, can use LocalGetData() to get the item without deadlocking
return item;
}
void PutData(DataItem item)
{
ReadLock write(lock);
//put item in database
}
private:
DataItem LocalGetData(int index)
{
return data[index];
}
}