Библиотека потоков С++ 0x или Boost.thread определяют функцию шаблона с переменным числом переменных, не являющуюся членом, которая блокирует все блокировки, избегая тупиковой блокировки.
template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
Хотя эта функция помогает избежать взаимоблокировки, стандарт не включает связанную блокировку области действия для написания безопасного кода исключения.
{
std::lock(l1,l2);
// do some thing
// unlock li l2 exception safe
}
Это означает, что нам нужно использовать другой механизм, такой как блок try-catch, чтобы сделать код безопасным для исключений, или определить нашу собственную блокировку с ограниченной областью действия для нескольких мьютексов, или даже сделать это.
{
std::lock(l1,l2);
std::unique_lock lk1(l1, std::adopted);
std::unique_lock lk2(l2, std::adopted);
// do some thing
// unlock li l2 on destruction of lk1 lk2
}
Почему стандарт не включает блокировку области действия для нескольких мьютексов одного типа, например
{
std::array_unique_lock<std::mutex> lk(l1,l2);
// do some thing
// unlock l1 l2 on destruction of lk
}
или кортежи мьютексов
{
std::tuple_unique_lock<std::mutex, std::recursive_mutex> lk(l1,l2);
// do some thing
// unlock l1 l2 on destruction of lk
}
Что-то не так с дизайном?
Обновлено: описание из стандарта
template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
Требования: каждый тип параметра шаблона должен соответствовать требованиям Mutex, за исключением того, что вызов try_lock() может вызвать исключение. [Примечание. Шаблон класса unique_lock соответствует этим требованиям при правильном создании экземпляра. -конец примечания]
Эффекты: все аргументы блокируются с помощью последовательности вызовов lock(), try_lock() или unlock() для каждого аргумента. Последовательность вызовов не должна приводить к взаимоблокировке, но в остальном она не определена. [Примечание. Должен использоваться алгоритм предотвращения взаимоблокировок, такой как попытка и откат, но конкретный алгоритм не указан, чтобы избежать чрезмерного ограничения реализации. — конец примечания ] Если вызов lock() или try_lock() вызывает исключение, unlock() должен вызываться для любого аргумента, который был заблокирован вызовом lock() или try_lock().
Я принял ответ. Я понимаю, что основная причина в том, что нет достаточно времени, чтобы сделать библиотеку C++0x Thread лучше. Я надеюсь, что TR2 будет включать в себя гораздо больше вещей.
scoped_multi_lock(T...)
. - person Georg Fritzsche   schedule 02.05.2010lock(...)
функции несбалансированы. По крайней мере, я бы также ожидал эквивалентногоunlock(...)
. Однако кажется, что лучше всего добавить такую функциональность в классlock_guard
. При этом его можно было построить с несколькими запирающимися предметами и разблокировать их при разрушении. В отличие от множества других шаблонных классов. - person GrafikRobot   schedule 02.05.2010