Имеет ли публичная функция getLock () или getMutex () антипаттерн?

Однажды я имел удовольствие попытаться выявить возможные проблемы параллелизма в кодовой базе C ++, где я продолжал видеть шаблон примерно так:

lock(obj.getLock());
obj.foo();
unlock(obj.getLock());

или хуже:

public void bar(SomeObject obj)
{
obj.foo;
}

lock(obj.getLock());
bar(obj);
unlock(obj.getLock());

Таким образом, мне пришлось просматривать каждое место, где вызывался foo (), и отслеживать, пока я не смог убедиться, что он доступен только из заблокированного контекста. (Технически не было явной разблокировки, потому что это были ограниченные блокировки, но вы поняли).

Я не могу придумать ни одной причины, по которой вы бы сделали это вместо того, чтобы объект SomeObj отвечал за свою собственную блокировку через частную блокировку всякий раз, когда foo вызывается так:

public void foo()
{
lock(myPrivateLock);
whateverFooDoes();
unlock(myPrivateLock);
}

Таким образом, я могу получить те же гарантии, не отслеживая ничего. Даже если вам нужно выполнить атомарную операцию сразу для нескольких классов, вы все равно можете создать утилиту, которая управляет собственной блокировкой для этого. К сожалению, я не смог найти ни одного источника, объясняющего, когда использовать публичный getLock (), и других, называющих его антипаттерном.

Есть ли время, когда вы должны / должны предоставлять публичную функцию getLock () вместо использования закрытых блокировок?

Спасибо

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …