Потокобезопасные контейнеры

maksimus1210
maksimus1210

В качестве примера можно привести приём данных по сети и передачу их в другой поток на обработку, кольцевого буфера в STL и так НЕТУ, так ещё из того, что есть в чистом виде непригодны для этого, нужно писать потокобезопасную надстройку над контейнером или вообще писать с нуля.

10
рейтинг
12 комментариев
mezastel
Плюсую. Потокобезопасные контейнеры прекрасно показали себя в .NET, так почему же не в С++?
mezastel
yndx-antoshkka
mezastel, в данном случае я только за :)

Другое дело, что это на 10 порядков сложнее чем кажется. Длительное время уже идёт обсуждение потокобезопасной очереди, возможно что к C++20 примут: open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0260r1.html

Другим предложением РГ21 уже занимается stdcpp.ru/proposals/fbd2bd33-c003-4475-a251-7c41b7d1c998 вместе с человеком из Intel. Пока что пытаемся придти к интерфейсу, который всех удовлетворит.

Если вы хотите другие потокобезопасные контейнеры - пишите прототип. Как будет прототип - могу помочь с proposal.
yndx-antoshkka
maksimus1210
yndx-antoshkka, Можно ли получить простой пример прототипа, что бы на его основе создать желаемое? Я не гуру в С++, но пишу на нём уже давно, привык к библиотекам Qt и к их стилю, а стиль BOOST и STL для меня - ад! Но для общего блага постараюсь сделать прототип в стиле STL.
maksimus1210
yndx-antoshkka
maksimus1210, а какой контейнер вы хотите? Можно делать в стиле Qt - главное показать что оно работает и функционально.
yndx-antoshkka
maksimus1210
yndx-antoshkka, загрузил 3 контейнера на github, если нужно будет пояснения, то могу дописать комментарии.
github.com/maksimus1210/containers
maksimus1210
yndx-antoshkka
maksimus1210, на queue уже есть предложение, очень надуюсь что будет в C++20.

ring_buffer имеет недочёты в реализации:
* clear() нельзя вызывать конкурентно с другими методами
* size(), readCount() и writeCount() не имеют смысла в могопоточных контейнерах так как результатом невозможно воспользоваться - он становится неактуальным к моменту использования
* underflow переменных m_bytesForWrite и m_bytesForRead при одновременном заходе нескольких потоков в read/write
* отсутствие RAII - deadlock в случае исключений
* у меня очень много замечаний по производительности, но сначала надо исправить вышестоящие пункты.

P.S.: я предупреждал, что это сложнее чем кажется
yndx-antoshkka
maksimus1210
yndx-antoshkka, Эти контейнеры писались к конкретному случаю из двух потоков, когда один поток наполняет, а другой забирает.
maksimus1210
yndx-antoshkka
maksimus1210, как вы понимаете - пользователи стандартной библиотеки будут использовать этот контейнер на различных конфигурациях, с различным количеством потоков. Нужен прототип, который хорошо работает во всех случаях.
yndx-antoshkka
maksimus1210
yndx-antoshkka, Недавно решил вернуться в тему и вплотную заняться решением, я написал многопоточную минималистичную очередь QueueConcurrent используя только STL: github.com/maksimus1210/containers/blob/master/queueconcurrent.h
Мне понравился пример приведённый на этом сайте в новостях : stdcpp.ru/blog/poslednie-novosti-o-razvitii-c
собственно от него и оттолкнулся, хочется услышать экспертное мнение, что бы довести класс до юзабельного уровня, после чего приступить к реализации кольцевого буфера.
maksimus1210
maksimus1210
По ходу дела возник вопрос, если для того, чтобы добавить элемент в контейнер оператором переноса добавили метод emplace, то для того что бы извлечь его от туда также оператором переноса - нет ничего, во всяком случае в std::list и std::queue их нет, может эту тему также стоит отправить в предложения?
maksimus1210
yndx-antoshkka
maksimus1210, тяжёлую тему вы выбрали :)

Посмотрите существующее предложение на concurrent queue open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0260r1.html Оно уже обсуждается длительное время и несколько более масштабно (умеет иногда lock free, value_pop(), предлагает обёртки над существующими очередями и т.д.). Попробуйте разобраться в предложенном подходе, и предложить здесь свои дополнения/исправления.
yndx-antoshkka
maksimus1210
yndx-antoshkka, Тема действительно тяжёлая, в моих проектах используется передача потоковых данных из одного потока в другой, на обработку, и обратно. Для реализации использую очередь и кольцевой буфер. Смотрел реализацию кольцевого буфера в boost - совсем не то, что мне нужно, поэтому приходится писать свои велосипеды. Спасибо за ссылку, буду изучать.
maksimus1210
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).