2013-07-03 3 views
10

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

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

In instantiation of 'class boost::lockfree::queue >':

error: static assertion failed: (boost::has_trivial_destructor::value)

error: static assertion failed: (boost::has_trivial_assign::value)

Я был shown generally what these errors mean, но у меня нет никакой надежды когда-либо исправить эту проблему сам, так как я почти новенькая C++.

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

ответ

2

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

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

+2

Это не совсем так: вы можете поместить необработанные указатели в очередь и освободить их, когда вы поместите указатель. например 'queue-> consume_all ([] (std :: string * str) {do_something (str); delete str;});' – Zero

10

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

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

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

+0

Спасибо, отлично справляется с spsc_queue! – Austin

8

I have no hope of ever fixing this myself, as I'm almost brand new to c++.

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

Is there an alternative way to pass text data between threads with lockfree ?

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

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

+0

Это получает +1, потому что я даже не рассматривал сохранение исходных указателей в очереди. –

+0

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

+0

. Ну вот, вы решили, что вы решили проблему, теперь это просто [простой вопрос программирования] (http: //www.catb .org/jargon/html/S/SMOP.html);) –

 Смежные вопросы

  • Нет связанных вопросов^_^