Как поместить std::string в boost:: lockfree:: queue (или альтернативу)?
Я пытаюсь поместить std::string
в boost::lockfree::queue
, чтобы мои потоки могли обновлять друг друга новыми данными.
Когда я пытаюсь использовать boost::lockfree::queue<std::string> updated_data;
, g++
говорит:
В создании экземпляра класса boost:: lockfree:: queue > :
Ошибка: статическое утверждение не выполнено: (boost:: has_trivial_destructor:: значение)
ошибка: статическое утверждение не выполнено: (boost:: has_trivial_assign:: значение)
Я был показан вообще, что означают эти ошибки, но у меня нет надежды когда-либо исправлять это сам, так как я почти новичок в С++.
Есть ли альтернативный способ передачи текстовых данных между потоками с помощью lockfree
? Если нет, пожалуйста, покажите мне, как положить std::string
в boost::lockfree::queue
.
Ответы
Ответ 1
Если вы помещаете необработанные указатели в очередь, старый std::strings
будет просочиться, поскольку освободить их невозможно, если они больше не нужны. Это связано с тем, что невозможно освободить объекты поточно-безопасным способом без фиксации (кроме некоторых трюков, таких как указатели опасности, которые boost::lockfree::queue
не используется)
По техническим причинам я действительно не понимаю, для boost::lockfree::queue
требуется тривиальный оператор присваивания и тривиальный деструктор, что означает, что ваш объект не может быть и не содержать какой-либо тип данных, который должен освобождать память в своем деструкторе, например std::string
.
Ответ 2
В документации boost::lockfree::queue
четко указано, что содержащийся элемент должен иметь тривиальное назначение и деструктор копирования, которые std::string
не имеет.
Если у вас есть один производитель и один потребитель, вы можете использовать spsc_queue
(http://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/spsc_queue.html), для которого требуется только конструктивная возможность и возможность копирования по умолчанию.
Если у вас есть несколько продюсеров или потребителей, вы будете застревать с обычной блокировкой (или настраиваемой строкой, которая не использует динамическое распределение).
Ответ 3
У меня нет надежды когда-либо исправлять это сам, так как я почти новичок в С++.
Тогда мне нужно задаться вопросом, почему вы возитесь с вещами, такими как блокированные очереди.
Есть ли альтернативный способ передачи текстовых данных между потоками с помощью lockfree
?
Да, вы можете просто сохранить указатель std::string*
к данным в очереди, потому что указатель является тривиальным типом и поэтому разрешен в очереди. Эквивалентно, вы можете сохранить reference_wrapper<std::string>
. Проблема заключается в том, что вам нужно хранить строки где-то в другом месте, чтобы иметь возможность указывать на них, поэтому теперь все, что вы сделали, это переместить проблему в другое место (например, вы могли бы поддерживать список строк в каждом потоке, и указатели хранилища для строки, управляемой извне, в свободной от блокировки очереди, но вы не знаете, когда можно безопасно удалить string
из списка для потоков, чтобы он увеличивался и увеличивался.)
Я бы предложил использовать простой std::queue<std::string>
и выполнить собственную синхронизацию с boost::mutex
и boost::condition_variable
или найти существующую реализацию потоковой (не блокирующей!) очереди.