Почему нет никаких ограниченных по объему блокировок для нескольких взаимных исключений в C++ 0x или Повышение. Поток?

C++ 0x библиотека потока или Boost.thread определяет нечлен variadic шаблонная функция, которые блокируют всю блокировку, избегающую тупика.

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&...);

Требует: Каждый шаблонный тип параметра должен отвечать Взаимоисключающим требованиям, за исключением того, что вызов к блокировке try_-() может выдать исключение. [Отметьте: unique_lock шаблон класса отвечает этим требованиям, когда соответственно инстанцировано. — заканчивают примечание]

Эффекты: Все аргументы заблокированы через последовательность вызовов, чтобы заблокировать (), try_lock (), или разблокировать () на каждом аргументе. Последовательность вызовов не должна приводить к мертвой блокировке, но является в других отношениях неуказанной. [Отметьте: алгоритм предотвращения мертвой блокировки, такой как try-and-back-off должен использоваться, но определенный алгоритм не указан, чтобы не сверхограничивать реализации. — заканчивают примечание], Если вызов для блокировки () или try_lock () выдаст исключение, разблокируйте (), то буду назван для любого аргумента, который был заблокирован вызовом для блокировки () или try_lock ().


Я имею, принимают ответ. Я понимаю, что главная причина состоит в том, потому что нет никакого достаточного количества времени для создания C++ 0x библиотекой Thread лучше. Я надеюсь, что TR2 будет включать намного больше вещей.

6
задан Vicente Botet Escriba 4 May 2010 в 14:09
поделиться

2 ответа

Я думаю, что предоставляя defer_lock_t (и adopt_lock_t), ожидается, что использование будет похоже на ваш второй пример, или, возможно, больше похоже на:

 std::unqiue_lock ul1(l1, std::deferred);
 std::unique_lock ul2(l2, std::deferred);
 std::lock(ul1, ul2);

Это безопасно для исключений и все такое хорошее.

Я, конечно, не могу претендовать на знание мыслей разработчиков, но я думаю, что они пытаются предоставить минимальный набор переносимых, безопасных примитивов. Скопированный множественный тип блокировки - это просто глазурь, и это глазурь, которую если в стандарте нужно указать и спроектировать, или в boost.thread, глазурь, которую нужно реализовать (и, конечно, в конечном счете, стандарт тоже должен заботиться о реализации, посмотрите, что случилось с экспортом).

3
ответ дан 17 December 2019 в 20:29
поделиться

Создание одного объекта, который блокирует несколько блокировок, не позволяет избежать взаимоблокировок не больше, чем их индивидуальная блокировка. Вы не можете заблокировать две блокировки одновременно ... если только вы не используете два потока, которые нарушают суть. Это верно, даже если вы поместите их в одно и то же утверждение.

-1
ответ дан 17 December 2019 в 20:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: