2013-08-06 1 views
1

Мне нужно сделать некоторые высокопроизводительные материалы C++, и поэтому мне нужно избегать копирования данных по возможности.Назначить строку zmq :: message_t без копирования

Поэтому я хочу напрямую назначить строковый буфер объекту zmq :: message_t без его копирования. Но, похоже, есть некоторая освобождение строки, которая позволяет избежать успешной отправки.

Вот кусок кода:

for (pair<int, string> msg : l) { 
    comm_out.send_int(msg.first); 
    comm_out.send_int(t_id); 

    int size = msg.second.size(); 
    zmq::message_t m((void *) std::move(msg.second).data(), size, NULL, NULL); 
    comm_out.send_frame_msg(m, false); // some zmq-wrapper class 
} 

Как я могу избежать того, что строка освобождаться до сообщение отправить? И когда строка освобождается точно?

С уважением

ответ

1

Я думаю, что, вероятно, zmq::message_t m((void *) std::move(msg.second).data()... неопределенное поведение, но, безусловно, является причиной вашей проблемы. В этом случае std::move не делает то, что, как я подозреваю, вы думаете.

Звонок в std::move фактически создает анонимное временное значение строки, перемещая содержимое msg.second в него, а затем передавая указатель на эти временные данные в конструктор message_t. Код 0MQ предполагает, что указатель действителен, но временный объект уничтожается после завершения конструктора message_t - т. Е. До того, как вы вызовете send_frame.

Zero-copy - сложный вопрос в 0mq (см. the 0MQ Guide) для получения более подробной информации, но вы должны убедиться, что данные, которые не были скопированы, действительны до тех пор, пока 0MQ не сообщит вам, что оно завершено с ним.

Использование строк C++ в этой ситуации hard, и требует много размышлений. Ваш вопрос о том, как «избежать того, чтобы строка была освобождена ...», подходит к сути проблемы. Единственный ответ на это - «с большой осторожностью».

Короче говоря, вы уверены, что вам нужна нулевая копия?

+0

Дорогой SteveL, нулевая копия всегда приятнее для высокопроизводительных. Если можно избежать копирования, это должно быть сделано. Разве вы так не думаете? В общей сложности это 33 МБ, которые необходимо скопировать. Моим вторым способом реализовать это было бы расширение zmq.hpp другим конструктором, который берет строку && и которая применяет эту строку к строке класса. Что вы думаете об этой идее? С уважением – moo

+0

@ user2237976 - нулевая копия может сделать код трудным для записи правильно и трудно читать, поэтому делать это всегда не всегда правильно. Я бы не рекомендовал менять код 'zmq.hpp' - это немного проблема обслуживания, когда вы хотите обновить, но подход кажется возможным. Возможно, вы могли бы обернуть 'zmqcpp' в свою собственную абстракцию или действительно обернуть собственную библиотеку 0MQ C с необходимыми изменениями. – SteveLove

+0

Поскольку этот код является всего лишь предметом исследования, нет необходимости в том, чтобы он был очень читабельным или совместимым с любой библиотекой. Я проверю, работает ли мой подход и расскажет вам об этом. – moo

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