Как поместить std::string в boost::lockfree::queue (или альтернативу)?

Я пытаюсь поставить std::stringс в boost::lockfree::queues, чтобы мои темы могли обновлять друг друга новыми данными.

Когда я пытаюсь использовать boost::lockfree::queue<std::string> updated_data;, g++ говорит:

В экземпляре класса boost:: lockfree:: queue>:

ошибка: статическое утверждение не удалось: (boost:: has_trivial_destructor:: value)

ошибка: статическое утверждение не удалось: (boost:: has_trivial_assign:: value)

Мне в общем показали, что означают эти ошибки, но у меня нет надежды когда-либо исправить это самостоятельно, так как я почти новичок в C++.

Есть ли альтернативный способ передачи текстовых данных между потоками с lockfree? Если нет, пожалуйста, покажи мне, как поставить std::string в boost::lockfree::queue,

3 ответа

Решение

Если вы поместите сырые указатели в очередь, старый std::strings будет утечка, так как нет возможности освободить их, когда они больше не нужны. Это потому, что нет способа освободить объекты потокобезопасным способом без взятия блокировки (кроме некоторых трюков, таких как указатели опасности, которые boost::lockfree::queue не использует)

По техническим причинам я не очень понимаю, boost::lockfree::queue требует тривиального оператора присваивания и тривиального деструктора, что означает, что ваш объект не может содержать или содержать какой-либо тип данных, который должен освобождать память в его деструкторе, например std::string,

boost::lockfree::queue документация ясно заявляет, что содержащийся в нем itemm должен иметь тривиальное назначение копирования и деструктор, который std::string не имеет

Если у вас есть один производитель и один потребитель, вы можете использовать spsc_queue ( http://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/spsc_queue.html), который требует только конструктивности и копируемости по умолчанию.

Если у вас несколько производителей или потребителей, вы застрянете в обычной очереди блокировки (или в пользовательской строке, которая не использует динамическое распределение).

У меня нет надежды когда-либо исправить это самостоятельно, так как я почти новичок в C++.

Тогда я должен задаться вопросом, почему вы возитесь с такими вещами, как безблокировочные очереди.

Есть ли альтернативный способ передачи текстовых данных между потоками с lockfree?

Да, вы можете просто хранить std::string* указатель на данные в очереди, потому что указатель является тривиальным типом и поэтому разрешен в очереди. Эквивалентно, вы могли бы хранить reference_wrapper<std::string>, Проблема в том, что вам нужно хранить строки где-то еще, чтобы иметь возможность указывать на них, так что теперь все, что вы сделали, это переместили проблему куда-то еще (например, вы могли бы поддерживать список строк в каждом потоке и храните указатели на внешне управляемую строку в очереди без блокировки, но вы не знаете, когда безопасно удалить string из списка на поток, так что он растет и растет.)

Я бы предложил вам использовать простую std::queue<std::string> и сделать свою собственную синхронизацию с boost::mutex а также boost::condition_variableили найдите существующую реализацию многопоточной (не блокируемой!) очереди.

Другие вопросы по тегам