DCLP. Паттерн или анти-паттерн?
От: Максим Рогожин Россия  
Дата: 10.04.18 17:24
Оценка:
Привет!
Читаю статью на википедии про Блокировку с двойной проверкой. Написано:

Блокировка с двойной проверкой (англ. Double checked locking) — параллельный шаблон проектирования, ...


На некоторых языках и/или на некоторых машинах невозможно безопасно реализовать данный шаблон. Поэтому иногда его называют анти-паттерном.


Если работает не гарантированно, то значит все таки анти-паттерн, так?

Объясните, пожалуйста.

UPDATE:
Стоит им пользоваться или лучше не надо?
Отредактировано 10.04.2018 17:26 Максим Рогожин . Предыдущая версия . Еще …
Отредактировано 10.04.2018 17:26 Максим Рогожин . Предыдущая версия .
Re: DCLP. Паттерн или анти-паттерн?
От: watchmaker  
Дата: 10.04.18 18:00
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Читаю статью на википедии про Блокировку с двойной проверкой.

МР>Стоит им пользоваться или лучше не надо?

Всё просто: если есть сомнения, что полностью понимаешь проблему, про которую написано в википедийной статье (и в статьях на которую она ссылается), то значит пользоваться не надо.
Отредактировано 10.04.2018 18:06 watchmaker . Предыдущая версия . Еще …
Отредактировано 10.04.2018 18:01 watchmaker . Предыдущая версия .
Re: DCLP. Паттерн или анти-паттерн?
От: _NN_ www.nemerleweb.com
Дата: 10.04.18 18:18
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Привет!

МР>Читаю статью на википедии про Блокировку с двойной проверкой. Написано:
МР>

МР>Блокировка с двойной проверкой (англ. Double checked locking) — параллельный шаблон проектирования, ...


Какую задачу решаем ?
Начиная с C++11 статическая переменная будет сразу потокобезопасна.

Как вариант можно воспользоваться также std::call_once
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: DCLP. Паттерн или анти-паттерн?
От: Максим Рогожин Россия  
Дата: 10.04.18 18:35
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Какую задачу решаем ?


Изучаю многопоточное программирование. Конкретно никакую задачу не решаю сейчас. Просто хочу уточнить как следует относиться к DCL — это подход который годится только для некоторых языков/платформ или это все же общепринятый паттерн многопоточного программирования?
Re[3]: DCLP. Паттерн или анти-паттерн?
От: reversecode google
Дата: 10.04.18 18:43
Оценка:
многопоточное программирование начинается с прочтение книги
Энтони Уильямс Параллельное программирование на С++ в действии
сколько раз вы ее прочитали ?
прочитаете 100 раз, тогда и придете спрашивать
Re: DCLP. Паттерн или анти-паттерн?
От: rm822 Россия  
Дата: 10.04.18 21:29
Оценка: -1
МР>Если работает не гарантированно, то значит все таки анти-паттерн, так?
Года до 2004 процессоры были одноядерные, и это было вообще безопасно.
Потом нахрен уперлись в лимит частоты и начали плодить ядра и производители процессоров начали делать агрессивные оптимизации внутри.
Паттерн постепенно перестал работать и стал антипаттерном.

МР>UPDATE:

МР>Стоит им пользоваться или лучше не надо?
В современных реалих — не стоит. В стандартной библиотеке уже реализовано все.
Но разобраться почему так — я бы настоятельно порекомендовал (например тут https://stackoverflow.com/questions/2158804/handling-out-of-order-execution)
Re[2]: DCLP. Паттерн или анти-паттерн?
От: watchmaker  
Дата: 10.04.18 23:17
Оценка:
Здравствуйте, rm822, Вы писали:

МР>>Если работает не гарантированно, то значит все таки анти-паттерн, так?

R>Года до 2004 процессоры были одноядерные, и это было вообще безопасно.
R>Потом нахрен уперлись в лимит частоты и начали плодить ядра и производители процессоров начали делать агрессивные оптимизации внутри.
R>Паттерн постепенно перестал работать и стал антипаттерном.

Глупости. Антипаттерном его называют не из-за того, что он не работает, а из-за того, что при его написании легко ошибиться и сделать реализацию, которая не работает.
И про ядра и внутрипроцессорные оптимизации тоже мимо. Классическая ошибочная реализация (например, которая в википедии тоже приводится как пример ошибочной) сбоит даже на одноядерном процессоре без суперскалярности. Там проблема вовсе не с тем, что код когда-то идеально работал, а потом перестал.

R> В стандартной библиотеке уже реализовано все.

Это дельное замечание, что не стоит делать свои велосипеды для примитивов, которые уже реализованы в стандартной библиотеке.
Re[3]: DCLP. Паттерн или анти-паттерн?
От: rm822 Россия  
Дата: 10.04.18 23:42
Оценка: -1
W>Глупости. Антипаттерном его называют не из-за того, что он не работает, а из-за того, что при его написании легко ошибиться и сделать реализацию, которая не работает.
А где тут на плюсах ошибаться-то? Volatile забыть поставить?
W>Классическая ошибочная реализация (например, которая в википедии тоже приводится как пример ошибочной) сбоит даже на одноядерном процессоре без суперскалярности.
Там жаба-мракобесие, а у нас тут плюсы. На плюсах на старом одноядерном процессоре сломать сможешь?
Re[4]: DCLP. Паттерн или анти-паттерн?
От: watchmaker  
Дата: 11.04.18 00:05
Оценка: 14 (1) +1
Здравствуйте, rm822, Вы писали:

W>>Глупости. Антипаттерном его называют не из-за того, что он не работает, а из-за того, что при его написании легко ошибиться и сделать реализацию, которая не работает.

R>А где тут на плюсах ошибаться-то? Volatile забыть поставить?
В том и дело, что куча людей думают "А где тут на плюсах ошибаться-то?". В результате, делают свою реализацию, но таки ошибаются в ней. В этом-то вся подлость этого паттерна и состоит

W>>Классическая ошибочная реализация (например, которая в википедии тоже приводится как пример ошибочной) сбоит даже на одноядерном процессоре без суперскалярности.

R>Там жаба-мракобесие, а у нас тут плюсы.
Это не отменяет того, что есть баги общие для двух этих языков
Ну и там ссылка на годную статью с С++ спецификой указана.

R>На плюсах на старом одноядерном процессоре сломать сможешь?

Предлагаешь мне написать заведомо неработоспособную реализацию? То есть взять нормальную реализацию и добавить в неё баги? А смысл?
Re[5]: DCLP. Паттерн или анти-паттерн?
От: Ops Россия  
Дата: 11.04.18 05:54
Оценка: 8 (1) +1
Здравствуйте, watchmaker, Вы писали:

W>В том и дело, что куча людей думают "А где тут на плюсах ошибаться-то?". В результате, делают свою реализацию, но таки ошибаются в ней. В этом-то вся подлость этого паттерна и состоит


Так реализация действительно простая. Но граблей там полно, можно легко сделать такую же простую, но неправильную. Вот хорошая тема, как с примером работающей реализации, так и с кучей предложенных "улучшений", которые ее ломают http://rsdn.org/forum/cpp/2549182
Автор: remark
Дата: 18.06.07
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[4]: DCLP. Паттерн или анти-паттерн?
От: dead0k  
Дата: 11.04.18 11:13
Оценка: +3
Здравствуйте, rm822, Вы писали:

W>>Глупости. Антипаттерном его называют не из-за того, что он не работает, а из-за того, что при его написании легко ошибиться и сделать реализацию, которая не работает.

R>А где тут на плюсах ошибаться-то? Volatile забыть поставить?
Не удержусь от напоминания, что использование volatile в c/c++ для решения проблем многопоточности — антипаттерн.
Re[3]: DCLP. Паттерн или анти-паттерн?
От: Mr.Delphist  
Дата: 11.04.18 14:43
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Изучаю многопоточное программирование. Конкретно никакую задачу не решаю сейчас. Просто хочу уточнить как следует относиться к DCL — это подход который годится только для некоторых языков/платформ или это все же общепринятый паттерн многопоточного программирования?


Изучая многопоточное программирование, надо сразу понимать под какую архитектуру и железку это всё делается. Скажем, последние процы вообще внутри могут оказаться связкой NUMA-нодов, поэтому с конкурентным доступом к памяти может быть куда более нетривиально, чем обычно.
Re[3]: DCLP. Паттерн или анти-паттерн?
От: Pzz Россия https://github.com/alexpevzner
Дата: 11.04.18 14:49
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Изучаю многопоточное программирование. Конкретно никакую задачу не решаю сейчас. Просто хочу уточнить как следует относиться к DCL — это подход который годится только для некоторых языков/платформ или это все же общепринятый паттерн многопоточного программирования?


В области многопоточного программирования вообще любой подход годится только для некоторых языков/платформ.

С другой стороны, если ты столкнешься с экзотической платформой, на которой "общепринятые" методы в стиле windows или unix не работают, там будет предостаточно специфических особенностей и помимо того, что относится к многопоточному программированию
Re[4]: DCLP. Паттерн или анти-паттерн?
От: Pzz Россия https://github.com/alexpevzner
Дата: 11.04.18 14:50
Оценка: +2 :)
Здравствуйте, reversecode, Вы писали:

R>многопоточное программирование начинается с прочтение книги

R>Энтони Уильямс Параллельное программирование на С++ в действии

А как сам Энтони Уильямс начинал? Ведь когда он начинал, то этой книги еще не было...
Re[3]: DCLP. Паттерн или анти-паттерн?
От: Максим Рогожин Россия  
Дата: 11.04.18 16:32
Оценка:
Здравствуйте, watchmaker, Вы писали:

R>> В стандартной библиотеке уже реализовано все.

W>Это дельное замечание, что не стоит делать свои велосипеды для примитивов, которые уже реализованы в стандартной библиотеке.

Подскажите, а что является реализацией DCLP в стандартной библиотеке?
Re[4]: DCLP. Паттерн или анти-паттерн?
От: watchmaker  
Дата: 11.04.18 16:46
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Здравствуйте, watchmaker, Вы писали:


R>>> В стандартной библиотеке уже реализовано все.

W>>Это дельное замечание, что не стоит делать свои велосипеды для примитивов, которые уже реализованы в стандартной библиотеке.

МР>Подскажите, а что является реализацией DCLP в стандартной библиотеке?


Этот вопрос плохой. Не библиотека реализует DCLP, а библиотека в своей реализации может использовать DCLP (а может использовать что-то другое).
И важны именно эти примитивы, которые предоставляет библиотека или язык. Их надо использовать в первую очередь. А уж реализованы они через DCLP или как-то по другому — это детали. (Ну вот я знаю, что на моей платформе инициализация локальной static переменной делается компилятором через DLCP. И что? Я же в коде просто объявляю переменную: и уверен, что мало кого должно заботить как компилятор это реализует.)

А собственно, про примитивы во втором же сообщении
Автор: _NN_
Дата: 10.04.18
привели два самых популярных: локальный static и std::call_once.
Re[6]: DCLP. Паттерн или анти-паттерн?
От: Alexander G Украина  
Дата: 12.04.18 14:00
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Так реализация действительно простая. Но граблей там полно, можно легко сделать такую же простую, но неправильную. Вот хорошая тема, как с примером работающей реализации, так и с кучей предложенных "улучшений", которые ее ломают http://rsdn.org/forum/cpp/2549182
Автор: remark
Дата: 18.06.07


Эм, эта тема до появления std::atomic, начиная с C++11 всё проще.
Русский военный корабль идёт ко дну!
Re[7]: DCLP. Паттерн или анти-паттерн?
От: Ops Россия  
Дата: 12.04.18 14:22
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Эм, эта тема до появления std::atomic, начиная с C++11 всё проще.


Оно не проще, синхронизация вообще сложная вещь. А вот для конкретно этой задачи сейчас все просто и без атомиков, инициализация локальных статических переменных после C++11 потокобезопасна:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

6.7
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[5]: DCLP. Паттерн или анти-паттерн?
От: okman Беларусь https://searchinform.ru/
Дата: 13.04.18 08:03
Оценка:
Здравствуйте, dead0k, Вы писали:

D>использование volatile в c/c++ для решения проблем многопоточности — антипаттерн.


И какие альтернативы volatile в C? Или в старых версиях C++, где нет atomic?

Вот приведу тогда стандартный пример "антипаттерна":
int g_data_ready;
data * g_data;

void consumer_thread(void)
{
    while (!g_data_ready) {}
    consume_data(g_data);
}

void producer_thread(void)
{
    g_data = ...
    g_data_ready = 1;
}

Без volatile этот код правильно работать не будет.
Отредактировано 13.04.2018 8:10 okman . Предыдущая версия .
Re[6]: DCLP. Паттерн или анти-паттерн?
От: Alexander G Украина  
Дата: 13.04.18 08:29
Оценка:
Здравствуйте, okman, Вы писали:

O>Вот приведу тогда стандартный пример "антипаттерна":

int g_data_ready;
data * g_data;

void consumer_thread(void)
{
    while (!g_data_ready) {}
    consume_data(g_data);
}

void producer_thread(void)
{
    g_data = ...
    g_data_ready = 1;
}

O>Без volatile этот код правильно работать не будет.

С volatile тоже не будет, нужны ещё барьеры. Которые implamantation-specific.

Но некоторые имплементации могут обеспечивать правильную работу.

Так, в Visual Studio у компилятора есть ключ для управления семантикой volatile, который по умолчанию "как atomic" для x86-64, и "без гарантий" на ARM.
Русский военный корабль идёт ко дну!
Re[7]: DCLP. Паттерн или анти-паттерн?
От: okman Беларусь https://searchinform.ru/
Дата: 13.04.18 11:37
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>...

AG>С volatile тоже не будет, нужны ещё барьеры. Которые implamantation-specific.

На x86/x64 (MSVC) — будет. В частности, из-за определенных гарантий, которые
обеспечиваются платформой и компилятором.

AG>Так, в Visual Studio у компилятора есть ключ для управления семантикой volatile, который по умолчанию "как atomic" для x86-64, и "без гарантий" на ARM.


И все-таки, как можно было бы переписать код выше "правильно", без "антипаттернов" (при условии, что это чистый C, не C++)?
Re[8]: DCLP. Паттерн или анти-паттерн?
От: Alexander G Украина  
Дата: 13.04.18 11:46
Оценка:
Здравствуйте, okman, Вы писали:

O>И все-таки, как можно было бы переписать код выше "правильно", без "антипаттернов" (при условии, что это чистый C, не C++)?


В С11 тоже есть атомики, с memory order гарантиями.
ключевое слово _Atomic, заголовок <stdatomic.h>

В старых С и С++ без антипаттерна не обойтись в этом случае.
Русский военный корабль идёт ко дну!
Re[8]: DCLP. Паттерн или анти-паттерн?
От: watchmaker  
Дата: 13.04.18 12:07
Оценка:
Здравствуйте, okman, Вы писали:

O>На x86/x64 (MSVC) — будет. В частности, из-за определенных гарантий, которые обеспечиваются платформой и компилятором.


O>И все-таки, как можно было бы переписать код выше "правильно", без "антипаттернов" (при условии, что это чистый C, не C++)?


Странный ты В одном сообщении одновременно требуешь от собеседника решения на чистом языке. А сам ссылаешься на решение, которое завязано на особенности работы конкретного компилятора под конкретную платформу с конкретными его настройками. Как-то непоследовательно

Как бы известно, что volatile не даёт ни атомарности, ни барьеров, и вообще его роль в языке далека от задач многопоточности (на что как бы даже намекает тот факт, что volatile появился в языке как обязательная часть задолго до этой самой многопоточности).

А то, что некоторые компиляторы содержат расширения, которые меняют поведение некоторых языковых конструкций, — так это особенности этих компиляторов.
Re[9]: DCLP. Паттерн или анти-паттерн?
От: dead0k  
Дата: 13.04.18 12:16
Оценка: +1
Здравствуйте, Alexander G, Вы писали:
AG>В старых С и С++ без антипаттерна не обойтись в этом случае.
Видимо дело в том, что старые c/c++ не знали про многопоточность вообще. И жаловаться в этом случае на отсутствие атомиков — несколько странно. Как и пытаться впихнуть вместо них volatile.
Решение — использовать внешние костыли: interlocked под win, расширения gcc под лин, рукописные (как правило на асме) велосипеды под экзотику.
Отредактировано 13.04.2018 12:17 dead0k . Предыдущая версия .
Re[5]: DCLP. Паттерн или анти-паттерн?
От: rm822 Россия  
Дата: 13.04.18 18:08
Оценка:
R>>На плюсах на старом одноядерном процессоре сломать сможешь?
W> Предлагаешь мне написать заведомо неработоспособную реализацию? То есть взять нормальную реализацию и добавить в неё баги?
Я тебе предлагаю доказать свое смелое утверждение. Показать как классическая реализация DLC на плюсах с volatile будет сбоить "даже на одноядерном процессоре без суперскалярности".
Re[6]: DCLP. Паттерн или анти-паттерн?
От: dead0k  
Дата: 14.04.18 01:19
Оценка: +1
Здравствуйте, rm822, Вы писали:
R>Я тебе предлагаю доказать свое смелое утверждение. Показать как классическая реализация DLC на плюсах с volatile будет сбоить "даже на одноядерном процессоре без суперскалярности".
Зачем, когда все уже давно сделано: http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405772
В двух словах: даже если с помощью волатилов удастся защитить указатель — не удастся гарантировать, что поток, пришедший за синглтоном вторым, получит до конца собранный объект.
И да, проблема там рассматривается с точки зрения абстрактной c++ машины, т.е. нет суперскалярности, да и про многоядерность только в заключении.

n.b.
я надеюсь, ты не подразумеваешь под классической реализацией DCLP мерзость из примера 11 в статье
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.