Russian Qt Forum
Февраль 28, 2020, 00:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2 3 ... 712
1  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 27, 2020, 12:55
Код
C++ (Qt)
if (auto item_data = item.lock())
{
   item_data->doSomething();
   ...
}
Что тут громоздкого?
Да все. Невдобняк капитальный. Ведь вся содержательная часть - вызовы типа doSomething, все должно быть заточено под них. А тут мне надо заводить еще переменную, и/или как-то группировать по локу и.т.п. - та ну нафиг

И, как ни странно, мне кажется это куда менее "безопасным". Застрянет где-то item_data - и я могу долго парить айтемы что уже обречены.
2  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 27, 2020, 11:20
ОК, след вопрос, откуда мы возьмем шаред, если вы хотите удалять по raw-указателю?
Из самого айтема, шаред или в паренте или (для рута) m_self
Код
C++ (Qt)
struct CIem {
...
 
private:
TreeItemRef m_parent;
std::vector<std::shared_ptr<CItem>> m_children;
std::shared_ptr<CItem> m_self;    // not null for root
};
Не зациклится ли деструктор? Ну по-любому, даже в худшем случае, это решается через custom deleter. Но думаю (не проверял) этой проблемы не возникнет вообще. Когда шаред удаляет данные (нет больше владельцев), он сначала должен поставить указатель на данные = 0 (чтобы никто не успел схватить), а потом звать deleter. Поэтому когда дело дойдет до деструктора m_self - он уже нулевой.
3  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 26, 2020, 15:50
Тогда m_shared всегда содержит 0.
Не тормозите
Код
C++ (Qt)
bool Lock( void )
{
 if (!m_shared.get())
  m_shared = m_weak.lock();
 
 return m_shared.get();
}
4  Qt / Многопоточное программирование, процессы / Re: MP + plugins : Февраль 26, 2020, 11:13
Ну как всегда Улыбающийся Ладно, я рассматривал такие возможности:

1) Делать чисто "от хоста" т.е. хост зовет плагин для кадров N (текущий), N + 1, N + 2 и.т.д. Быстро убедился что это нереально т.к. это случай общий, требуется синхронизация ВСЕХ данных для каждого кадра. Ожидаемо/нормально, "слишком гордый/концептуальный" план редко бывает реальным. Придется удовлетвориться оптимизацией конкретного плагина, его данные от других не зависят.

2) Думал вообще распаковать все кадры во временный файл, а потом грузить данные "блоками" (API это позволяет, в хост подаются POD структуры без адресов). Тогда вроде и "разпоточивать" ничего не надо. Но вероятно получу проблемы с диском. Скромная свинка (аттач) - исходный файл уже 300 метров (кадров прилично), а распакованный даже "на глазок" раз в 5 больше.

Вообще то обстоятельство что пропуск кадров (drop frames) может случиться (и часто) и все пыхтение с подгрузкой "с запасом" окажется в минус - капитально охлаждает энтузиазм
5  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 26, 2020, 10:44
Не понял
shared не заполняем, он только для лока. Померещилось что шаред аргумент может меняться, но это не так - он подается по значению. Исправил

Конечно можно обойтись и без члена шаред, напр метод lock возвращает шаред, но класс его не хранит. Дело вкуса, мне больше нравится так, класс "самодостаточен", никакие др вумники (снаружи) не привлекаются.
6  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 25, 2020, 17:19
И что есть что?
Код
C++ (Qt)
template<class T>
struct CItemRef {
 CItemRef( std::shared_ptr<T> sh )  :
   m_weak(sh),
   m_raw(sh.get())
 {
 }
 
 T * data( void ) const
 {
   auto p = m_shared.get();  // locked?
   if (p) return p;
 
   if (m_raw)
     assert(!m_weak.expired());
 
   return m_raw;
 }
 
...
// data
 std::shared_ptr<T> m_shared;
 std::weak_ptr<T> m_weak;
 T * m_raw;
};

Edit: убрал "ненужные тонкости" в конструкторе
7  Qt / Многопоточное программирование, процессы / MP + plugins : Февраль 25, 2020, 12:54
Добрый день

Приложение крутит на экране анимацию кадр за кадром. На каждом кадре вызывается плагин который лезет в (большой) файл, находит там данные текущего кадра, из них создает модель, передает ее хосту, и тот рисует кадр. Все работает, но вот беда - по скорости/fps плохо. Ну оно и понятно, пока файл откроют, прочитают, хосту данные передадут... Подробности: общение с плагином - чисто С API. Превью имеет стандартную опцию "drop frames", напр после кадра 5 следующим может быть кадр 10 (если не успевает).

Ну и как "ускоряться"? Разумеется плагин ни о каком multi-threading никогда не слыхал, глобалок там туча  Плачущий Хост использует MP, но для др целей, общение с плагином глухо в main thread. В общем пока неясно даже "с какой стороны подлезть". Что посоветуете ?

Спасибо
8  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 25, 2020, 09:54

Как Вы относитесь к идее не использовать в современном С++ new и delete? Т.е. для создания объекта использовать функции типа make_unique/shared, а удаляться объект будет, когда его умные указатели помрут.
Это мы уже обсуждали
Код
C++ (Qt)
// int index
treeView->RemoveChildAt(index);
Против этого кода возражений нет (поправьте если не так). Но удалять "только так" не получится, неизбежна ситуация где индекса нет, а есть лишь "невладеющий" указатель. Т.е. никто умирать не собирался, надо мочить.

О другом (и более интересном). По-моему TreeItemRef должен быть инстансом такого
Код
C++ (Qt)
template<class T>
struct CItemRef {
...
// data
 std::shared_ptr<T> m_shared;
 std::weak_ptr<T> m_weak;
 T * m_raw;
};
typedef CItemRef<TreeItem> TreeItemRef;
 
И вроде это даже thread-safe. Или нет? Покритикуйте
9  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 24, 2020, 17:01
Но вы до сих пор не поняли, что DeleteItem это плохой, негодный метод Улыбающийся
Compare to ?  Улыбающийся
10  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 24, 2020, 13:15
Вы же всё пытаетесь решить проблему которую сами себе устроили "как бы мне вызвать делет на айтем чтобы ничего не покрашилось". Никак, в современной программе на с++ вообще нет new и delete. Когда холдер вышел из скопа, тогда и удалили. Желание вызвать магическую функцию которая удалит айтем, найдет его в паренте, вычистит его оттуда, пройдется по десятку хеш таблиц куда вы этот айтем сложили, такое желание, сорян, утопично.
Так Вы (как и всякий другой) такую ф-цию все равно писать будете, деваться-то некуда. Вот есть "айтем" - пусть хоть тот же Ваш обсервер. Надо удалить его из списка. Таскать за собой индекс - несерьезно. Надеяться на выход из скопа не приходится. Ваши действия?

Ну ладно, а что все-таки "отдавать наружу" чтобы удобно было там его юзать? Может так
Код
C++ (Qt)
TreeItemRef item = treeView->Root().childAt(0);
 
item.SetName("test");     // синтаксис или "семантика" (?) ссылки
if (CheckSomething(item))
DeleteItem(item);
 
if (!item.IsNull())
item.SetName("done");
 
if (item.Lock()) {
...
}
 
По-моему симпатично и ф-ционально. Хочу только проверяю, хочу лочу, хочу ничего. Удобно и гибко. Но чем должен быть такой TreeItemRef ? Очевидно обсервер не годится, у него нет нужного ф0ционала. Но weak_ptr тоже будет неудобен и громоздок. Нужен "сахар", обертки, и все такое

Вот обсервер ровно для этого и нужен
Это все давно поняли, не тратьте свое время поясняя это снова и снова. Но ведь цель написания - достичь полезного рез-та, а не использовать "максимально подходящий" стандартный класс (за неимением другого).
11  Qt / Общие вопросы / Re: QByteArray между потоков через сигналы-слоты фрагментирует память : Февраль 24, 2020, 12:37
Размеры QBytArray как написал выше, не превышают 2.5мб.
Я правильно понимаю, что надо делать QBytArray::reserve(кратно 4000) ?
Повторюсь - начните со сбора/печати статистики, часто это наталкивает на нужные мысли и почти всегда экономит массу времени

Есть сомнения, что "внутри" Qt-шных EventLoop-ов они такое же состояние по резервированию сохранят.
В смысле при передаче через слот/сигнал? Ну может и так, в худшем случае придется resize (а не reserve) и хранить размер. Неприятно но не смертельно

PS: майн кампф за память идет от необходимости запускать подобных процессов довольно много (форком или вручную, пока не решил), думаю за 100 штук легко перевалит.
Это уже др вопрос или тема
12  Qt / Общие вопросы / Re: QByteArray между потоков через сигналы-слоты фрагментирует память : Февраль 23, 2020, 10:50
Вопрос: какие методы можно применить для уменьшения фрагментации, при условии, что на каждом этапе обработки нужна своя "копия" QByteArray?
Для начала убедиться что проблема именно в фрагментации собрав статистику QBytArray.size(). Вообще 500 метров - по нынешним временам дело рядовое. Сама борьба с фрагментацией всегда сводится к одному - выделять блоки одинакового размера, напр кратные 4K (только не 4096, а чуть меньше, напр 4000). Соорудить что-то типа QAlignedByteArray
13  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 23, 2020, 10:26
То есть предлагается делать delete item который сам на себя держит шаред. Я всё верно понял?
Да. И подозреваю не мне первому это пришло в голову, сейчас тыкнут в нос какой-нибудь хабровской статейкой  Улыбающийся

Вся "вумность" тут вокруг юников,
Да, и если бы было "по уму" (можно брать weak от юника) то все совершенно очевидно, и проблемы нет.

..а чем мы наружу смотрим вообще не важно - ровно один и тот же код был бы без "вумников" на голых указателях.
Вообще-то важно, задумка (как я понял) была работать "без указателей/ссылок", с наглой мордой подавая/возвращая все по значению. Поэтому про голые надо забыть.

Кстати тут упоминалось что weak принципиально не имеет get(), а только lock(). Это выглядит очень "идейным", мол, написать неправильно просто не получится! Но по жизни есть масса ситуаций когда multi-threading просто не интересует, и навязанный lock() очень утомителен. Заметим что в (якобы отсталой) Qt реализации это учитывается.

Из этих соображений обсервер надо оставить, но конечно иметь и геттеры "по всем правилам", напр LockItem(). Тогда все хорошо.
14  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 22, 2020, 12:58
Вы не понимаете, зачем вообще нужен ObserverPointer
Ну почему обязательно "не понимает" (не знает, не читал и.т.п  Улыбающийся)? Может и понимает, но не считает это хорошим , правильным, имеет др мнение. Такой вариант вполне возможен Улыбающийся

Лично я думаю что указатель никак не может считаться "вумным" если у него нет проверки валидности. И, видимо, не я один если обсервер "experimental".

есть shared/weak и только эта пара может обеспечить безопасность в multi-thread.
Это лишь атомарная блокировка удаления, как бы "необходимое", но совсем не "достаточное", никакой безопасности она сама по себе еще не обеспечивает. Ну сработал lock(), т.е. "жизнь продлена", но ведь это может случиться в N нитках.

Но они нафиг не нужны в задаче с деревом. У меня нет проблемы проследить за временем жизни айтемов потому что паттерны использования достаточно простые - добавить новый айтем в конец, отсортировать айтемы, удалить айтем.
Ну допустим. Но так ли уж страшен вариант с полноценным weak (вместо калечного обсервера)? Не перемудрил ли я в прошлый раз? А если так
Код
C++ (Qt)
struct CIem {
typedef std::weak_ptr<CItem>  TItemPtr;
...
 
private:
TItemPtr m_parent;
std::vector<std::shared_ptr<CItem>> m_children;
std::shared_ptr<CItem> m_self;    // not null for root
};
 
Ну и вроде все то же что у Вас, ну чуть за root'ом присмотреть
15  Qt / Общие вопросы / Re: Qt + вумные указватели : Февраль 21, 2020, 12:05
Вектор юников можно спокойно мувать в функцию или возвращать из функции по значению.
Т.е. сработает лишь конструктор перемещения (а он у юника имеется)
То же самое относится и к конструктору по умолчанию у Т, некоторые кутешные контейнеры требуют его наличия, когда стандартным пофиг.
Наверно речь идет о "некоторых" контейнерах, напр std::vector.resize() потребует дефаултный конструктор

Вы упорно пытаетесь хранить стейт (хотя бы выше по стеку) и находите всё новые и новые баги ругая всё подряд.
Не совсем так, сохранить state я не пытаюсь, против изменения итераторов возражений нет. НО валидность (isNull) должна быть, иначе это дискредитирует саму идею вумных указателей. Ну в самом деле, нафиг они нужны если имею все те же проблемы голых?

Не сработает и не должна.
А мне кажется обеспечить валидность можно. И "без великов". Попробуем так
Код
C++ (Qt)
struct CIem {
typedef std::weak_ptr<CItem>  TItemPtr;
...
 
private:
TItemPtr m_parent;
std::vector<std::shared_ptr<CItem>> m_children;
};
 
Конечно юзать шаред не есть хорошо. Но мы постараемся зажать его в рамках класса. Здесь так не выходит - никак не объявить root (или take). Поэтому предлагаю так
Код
C++ (Qt)
struct CIem {
typedef std::weak_ptr<CItem>  TItemPtr;
...
 
private:
TItemPtr m_parent;
std::vector<TItemPtr> m_children;
 
typedef std::list<std::shared_ptr<CItem>> TList;
TList m_list;
TList::iterator m_iterator;
};
 
m_list хранит шаред чилдренов, а если это root - то и шаред на себя. Тогда
Код
C++ (Qt)
// static
bool CItem::DeleteItem( TItemPtr itemPtr )
{
 auto item = itemPtr.lock();
 if (!item) return false;
 auto parent = item->parent().lock();
 if (parent)
   parent->removeChild(item.get());
 else
  item->m_list.erase(m_iterator);
 return true;
}
 
CItem::~CItem( void )
{
 while (m_children.size())
   DeleteItem(m_children.front());
}
Попинайте
Страниц: [1] 2 3 ... 712

Страница сгенерирована за 0.296 секунд. Запросов: 23.