Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QByteArray & move семантик |
Автор: xbarmaglot 17.5.2017, 14:18 |
Обрабатываю сетевой трафик. Протокол не имеет значение. Поток разбивается на пакеты и каждый пакет кладется в QByteArray (1-ое копирование). Этот пакет кладется в очередь реализованную на QQueue (2-ое копирование) Очередь синхронизированная т.к. много писателей-один читатель. Далее из очереди выбираются данные для обработки (3-е копирование). После этого пакет разбирается и далее передается по ссылке в цепочку обязанностей. Сам пакет константный и не изменяется. По сути хотелось бы один раз в буфер положить пакет, а далее просто передавать его на обработчики. Можно использовать и умные указатели, то после появления move и поддержки его в qt логично было бы просто передавать права владения на объект без копирования. 1. Как это делается в qt? (std::move?) 2. Как реализовать передачу прав владения для очереди и забрать из очереди тоже без глубокого копирования? |
Автор: ss 17.5.2017, 20:32 |
auto arr = QByteArray::fromRawData(srcPtr, size) - это указывает на данные. "=" - Данные не скопирует т.к. этот оператор перегружен для временного объекта (rvalue) inline QByteArray &operator=(QByteArray &&other) Q_DECL_NOTHROW { qSwap(d, other.d); return *this; } еще вот такая функ qSwap(). |
Автор: xvr 18.5.2017, 12:10 |
В Qt почти все контейнеры реализуют implicit sharing (QByteArray точно реализует), так что никакого копирования данных при копировании самих QByteArray не происходит (пока вы не попытаетесь поменять содержимое какой нибудь копии этого самого QByteArray) |
Автор: xvr 18.5.2017, 13:42 |
Разное. Но если вы боретесь с оверхедом при передачи контейнера по цепочке обработчиков, то отложенное копирование само по себе сводит этот оверхед практически к нулю. Реализация передачи прав владения в таком окружении уже ничего не даст (с точки зрения уменьшения накладных расходов), ну и собственно просто не имеет смысла. |
Автор: xbarmaglot 18.5.2017, 14:22 |
меня беспокоит не цепочка обязанностей по ссылке, а тройное копирование при помещении пакета в очередь |
Автор: xvr 18.5.2017, 15:50 |
Физического копирования данных не происходит, на то и implicit sharing. При присваивании одного QByteArray в другой [пустой] реально происходит копирование 1 поинтера и инкремент 1 целого числа. Так что не беспокойтесь - это очень дешевая операция ![]() |
Автор: Alexeis 19.5.2017, 10:49 | ||
А если я создам копию для использования в другом потоке (передам через асинхронный сигнал слот), после чего 2 потока попытаются одновременно изменить содержимое двух якобы копий? Получится 3 экземпляра, один из которых повиснет в виде утечки памяти? |
Автор: xvr 19.5.2017, 12:15 | ||
Нет. Первое же изменение сделает 2 отдельных копии, которые и будут меняться. То, что они в разных потоках не помешает - счетчик ссылок выполнен на основе атомарных операций, изготовление копии тоже делается в поток безопасном виде. |