Просмотр сообщений
|
Страниц: 1 2 3 [4] 5 6 ... 39
|
46
|
Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself
|
: Март 15, 2021, 12:54
|
Всё даже может быть намного хуже, если полностью прочитать документацию)). Note that deleting a QThread object will not stop the execution of the thread it manages. Deleting a running QThread (i.e. isFinished() returns false) will result in a program crash. Wait for the finished() signal before deleting the QThread.
|
|
|
47
|
Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself
|
: Март 15, 2021, 12:49
|
Собственно, это всего лишь предупреждение, и wait в этом случае ничего не делает. Убираем wait, остается выход из циклов обработки событий quit и отложенное удаление объекта QThread с помощью deleteLater. Вопрос остается - это правильно?
Удаление объекта QThread само по себе не завершает активность (Note that deleting a QThread object will not stop the execution of the thread it manages.). Метод wait же ожидает завершения активности. В общем случае, второй вариант допускает "подвешивание" незавершенных активностей, особенно если они реализованы в виде бесконечных циклов (когда реализована собственная версия метода MyThread::run() ).
|
|
|
48
|
Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself
|
: Март 15, 2021, 11:42
|
ждать в себе завершения самого себя бессмысленно)).
Это ж и есть ответ на вопрос. Вызов деструктора Worker производится в активности потока workerThread, который и предлагается подождать с помощью workerThread->wait(). В первом же варианте вызов деструктора Controller производится в активности другого (скорее всего, главного) потока, связанного с объектом Controller. Здесь можно и подождать workerThread->wait().
|
|
|
50
|
Qt / Многопоточное программирование, процессы / Re: Не масштабится :-(
|
: Март 10, 2021, 16:48
|
Такое "деление на диапазоны" (иногда называют "stencil") совсем не бесплатно/безобидно. И предрассчитать его получается далеко не всегда.
Найти (или предположить) диапазон значений индексов - откуда здесь могут быть большие затраты? Я бы делал просто "мешком локеров", напр для Qt
Любые локеры сделают только хуже. Здесь может только помочь распараллеливание безо всяких локеров. Все потоки пробегаются по всему циклу, только производят вычисления каждый в своем диапазоне. В своих задачах я формирую массивы типа faces заранее (увеличиваю только при необходимости), чтобы не иметь потерь на new|delete. Использование заранее инициированного пула потоков и ожидание на барьере после первого цикла и далее после второго ничтожно по сравнению с затратами на вычисления. И да, расчеты нормалей, как правило делают на GPU.
|
|
|
51
|
Qt / Многопоточное программирование, процессы / Re: Не масштабится :-(
|
: Март 10, 2021, 12:22
|
Номера индексов mNorIndex поделить на диапазоны. Первым потоком выполнять операции только для [0...N1), вторым - [N1...N2) и т.д. [Nx...mNorIndex.size()).
Правильно так: Значения индексов mNorIndex поделить на диапазоны. Первым потоком выполнять операции только для [0...N1), вторым - [N1...N2) и т.д. [Nx...max_index)). Где max_index, максимальное значение из mNorIndex.
|
|
|
52
|
Qt / Многопоточное программирование, процессы / Re: Не масштабится :-(
|
: Март 10, 2021, 12:17
|
Нужно убрать цикл из цикла, а затем уже параллелить C++ (Qt) std::vector<Vec3> CPolySDS::CalcVerNormals( const std::vector<Vec3> & pos ) const { std::vector<Vec3> dst(pos.size()); std::vector<Vec3> faces( mNorIndex.size() / mNumVerPerFace ); // эффективно распараллеливаем здесь for (size_t i = 0; i < mNorIndex.size(); i += mNumVerPerFace) { faces[ i / mNumVerPerFace ] = GetFaceNormal(&mNorIndex[i], mNumVerPerFace, pos); } // не очень эффективно распараллеливаем здесь for (size_t i = 0; i < mNorIndex.size(); i += mNumVerPerFace) { for (size_t j = 0; j < mNumVerPerFace; ++j) dst[mNorIndex[i + j]] += faces[ i / mNumVerPerFace ]; } // ну и далее вектор посылается на видеокарту
Как вариант не очень эффективное распараллеливание попробовать реализовать без блокировок диапазонами таким способом Номера индексов mNorIndex поделить на диапазоны. Первым потоком выполнять операции только для [0...N1), вторым - [N1...N2) и т.д. [Nx...mNorIndex.size()). Диапазоны нужно выбирать так, чтобы кеши CPU заведомо не пересеклись.
|
|
|
53
|
Программирование / Общий / Re: Десериализация UI
|
: Декабрь 25, 2020, 13:43
|
Так не катит Собсно десериализация - это "тривиально" (здесь это слово подходит). Сначала создаем объект конструктором и потом читаем из потока, объект всегда валиден. Но в данном случае я не могу безболезненно создать объект (см примеры классов выше). Сделал так Поэтому я и предложил отделить сериализацию от объекта. Фабрика может создавать не сам Control, а ControlSerializator, который в свою очередь вычитывает из stream необходимые параметры и, если все ОК, создает Control.
|
|
|
54
|
Программирование / Общий / Re: Десериализация UI
|
: Декабрь 23, 2020, 10:17
|
Однако дефаулт конструктор оказался очень неудобным (при переводе на Qt) , и я решил вместо Init иметь нормальные конструкторы во всех классах наследниках (десятка 2). Конечно развалилась хвабрика чтения. Нужно ли ее "домучивать"? Или лучше сбацать в духе "современного С++", там function, bind и все такое? Тогда как?
Почему фабрика развалилась? В фабрике нельзя просто заменить make() на make( QWidget * parent, Qt::WindowFlags ) или что там используется? Можно вообще сделать отдельно Qt Widgets и оставить эту сериализацию. C++ (Qt) class MyWidget : public QWidget { public: MyWidget ( QWidget * parent, Qt::WindowFlags ); };
C++ (Qt) class BaseControlSerializer { BaseControlSerializer( void ); virtual void Init( QWidget * win, const std::string & txt ... ) = 0; ... virtual const std::string & SerialName( void ) const; ... virtual void Read ( Stream & stream ) = 0; virtual void Write( Stream & stream ) = 0; virtual QWidget * widget () = 0; }; template < typename _Widget > class GenericControlSerializer : public BaseControlSerializer { _Widget * m_widget; private: GenericControlSerializer ( void ); virtual void Init( QWidget * win, const std::string & txt ... ) override; ... virtual void Read ( Stream & stream ) override; virtual void Write( Stream & stream ) override; virtual QWidget * widget () override { return m_widget; }; };
|
|
|
56
|
Qt / Вопросы новичков / Re: Нужно переделать управление персонажа под тригонометрию с поворотом картинки.
|
: Декабрь 22, 2020, 08:09
|
C++ (Qt) void MyItem::keyPressEvent(QKeyEvent *event) { auto key = event->key(); if (key == Qt::Key_Up && speed<maxSpeed) if (speed < 0) speed += dec; else speed += acc; if (key == Qt::Key_Down && speed>-maxSpeed) if (speed > 0) speed -= dec; else speed -= acc; if (key != Qt::Key_Up && key != Qt::Key_Down) if (speed - dec > 0) speed -= dec; else if (speed + dec < 0) speed += dec; else speed = 0; if (key == Qt::Key_Right && speed!=0) angle += turnSpeed * speed/maxSpeed; if (key == Qt::Key_Left && speed!=0) angle -= turnSpeed * speed/maxSpeed; car[0].speed = speed; car[0].angle = angle; }
|
|
|
57
|
Qt / Вопросы новичков / Re: Как вызываются деструкторы
|
: Декабрь 15, 2020, 12:19
|
Здесь собственно отвечать не на что. По каждому вопросу нужно отправлять учить основы C++. 1. Нет, не правильно. См. https://doc.qt.io/qt-5/objecttrees.html2. Нет, не правильно. Что значит статически и что такое деструктор, когда он вызывается и нужно ли его вызывать явно? 3. То же самое. Читайте про область видимости переменных и порядок их инициализации и удаления. 4. Тоже полная ерунда написана. Следует из непонимания 2 и 3.
|
|
|
58
|
Qt / Общие вопросы / Re: Корутины (модное слово)
|
: Октябрь 21, 2020, 17:58
|
Корутина - это объект с конкретным состоянием. Чтобы завершить корутину, достаточно удалить конкретный её экземпляр. Если необходимо запустить корутину "с нуля", то необходимо сформировать другой экземпляр корутины.
|
|
|
60
|
Qt / Qt-инструментарий / Re: кракозябры в QtCreator
|
: Октябрь 12, 2020, 22:27
|
Это конечно уникально...!!! QtC в одной make-сесии умудряется черт знает в каких кодировках выдавать сообщения. И такие кракозябры, и такие - выбирай на любой вкус. Какая ещё IDE даст такую свободу выбора? )))
Не понятен наезд на QtC. Это проблема командной строки и применения разнородных инструментов. Так уж получилось, что QtC может работать в разных сочетаниях, но за вывод в консоль отвечает конкретное приложение, а не IDE. При сборке проекта из командной строки без QtC как обстоит дело с кракозябрами?
|
|
|
|
|