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

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4 5   Вниз
  Печать  
Автор Тема: Тестовое задание на программиста С++/Qt компания некстерс  (Прочитано 49322 раз)
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #30 : Сентябрь 04, 2016, 16:17 »

В википедии и не то напишут. Вот такие люди, начитавшиеся википедии, считают себя самыми умными.

конкретнее - что там написано не так ?
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #31 : Сентябрь 04, 2016, 16:20 »

При том, что они сами сказали что GUI всегда однопоточный и спросили почему.
Это "всем известно" но никто не знает "почему". Во всяком случае неубогое Вындоуз может создавать окна в др потоке.

наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #32 : Сентябрь 04, 2016, 17:07 »

наверно потому что классы, работающие с gui не потокобезопасны
Хммм.. а как же рисование в QImage/QPiхmap? Оно ведь вроде безопасно?

(что может следовать также из принципов работы с графикой)
А шо там за прынцыпы такие? Расскажите, мне об этом ничего не известно
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #33 : Сентябрь 04, 2016, 17:50 »

Чтобы "программист GUI" этот самый GUI не развалил Улыбающийся, особенно если там многопоточность присутствует.
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

Где-то уже видел ответ на этот вопрос Улыбающийся
Насколько я помню, ответ был в том, что с гуем работает человек и так получилось, что за окном приложения может за раз работать только один и выполняться только одно определенное действие: клик мыши, нажатие кнопки и т.п. Поэтому нет смысла создавать многопоточное гуи.
И такая концепция не мешает тому, что у приложения может быть несколько потоков: главное с гуи, остальные что-то делают и посылают уведомления гуи.
Записан

qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #34 : Сентябрь 04, 2016, 22:54 »

наверно потому что классы, работающие с gui не потокобезопасны
Хммм.. а как же рисование в QImage/QPiхmap? Оно ведь вроде безопасно?

QWidget and all its subclasses, are not reentrant
http://doc.qt.io/archives/qt-5.5/threads-qobject.html

(что может следовать также из принципов работы с графикой)
А шо там за прынцыпы такие? Расскажите, мне об этом ничего не известно

предполагаю организацию работы через хэндлы, работа с которыми из разных потоков не предусмотрена
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #35 : Сентябрь 05, 2016, 08:55 »

При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

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

наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)


Ничего сложного в реализации потокобезопасных классов для GUI нет, изначальная проблема совершенно в другом - в выбранной исходной архитектуре и стратегии обработки GUI событий.
Весь набор GUI в Qt представляет собой связанное дерево элементов, для которого необходимо обеспечить "правильный" порядок обработки GUI событий. То есть, например, прежде чем обработать событие HoverEnter для определенного элемента, для всех предыдущих элементов иерархии должны быть обработаны HoverEnter/HoverMove/HoverLeave. Так же предполагается доступ к родительскому и дочерним элементам во время обработки событий. При асинхронной обработке событий невозможно без сложных правил синхронизации (простые мютексы не гарантируют порядок обработки) обеспечить описанное выше поведение. Отсюда появляется архитектурное ограничение - обработка событий в одном потоке. При этом поток не обязан совсем быть главным! Он определяется лишь местом создания обработчика GUI событий. Например, код ниже работает без всяких проблем.

Код
C++ (Qt)
class Thread : public QThread
{
private:
int m_argc;
char ** m_argv;
 
public:
Thread ( int argc, char ** argv )
: m_argc( argc )
, m_argv( argv )
{
}
 
protected:
virtual void run ()
{
QApplication app( m_argc, m_argv );
QWidget widget;
widget.show();
app.exec();
}
};
 
// Начало приложения
int main ( int narg, char ** varg )
{
Thread thread( narg, varg );
thread.start();
thread.wait();
return 0;
}
 

Необходимо отметить, что сам процесс отображения, например, с помощью OpenGL вполне может быть вынесен в отдельный поток или даже в пул потоков.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #36 : Сентябрь 05, 2016, 08:57 »

Где-то уже видел ответ на этот вопрос Улыбающийся
Насколько я помню, ответ был в том, что с гуем работает человек и так получилось, что за окном приложения может за раз работать только один и выполняться только одно определенное действие: клик мыши, нажатие кнопки и т.п. Поэтому нет смысла создавать многопоточное гуи.
Слабоватая аргументация. Почему поток не может иметь свое окно(а) GUI которое он сам же и обновляет? Это вполне разумно

QWidget and all its subclasses, are not reentrant
http://doc.qt.io/archives/qt-5.5/threads-qobject.html
И что с того? Да, если я буду дергать setText из разных ниток - наверное рухнет. Ну так синхронизация всегда моя забота если ниток > 1

Может потому что событие рисования посылает ОС и обработчик этого события существует только в главной нитке? (ну это я так думаю, "правельный ответ" не знаю  Улыбающийся)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #37 : Сентябрь 05, 2016, 09:03 »

Отсюда появляется архитектурное ограничение - обработка событий в одном потоке. При этом поток не обязан совсем быть главным! Он определяется лишь местом создания обработчика GUI событий. Например, код ниже работает без всяких проблем.
Недавно изучал это место. Да, создать UI в "не главной" нитке можно, но будет использоваться другой EventDispatcher. c существенными отличиями.

Необходимо отметить, что сам процесс отображения, например, с помощью OpenGL вполне может быть вынесен в отдельный поток или даже в пул потоков.
С OpenGL можно рисовать синхронно, не дожидаясь события ОС. И что, даже из др нитки работает? (не проверял). Если так - то вот и решение, создал QOpenGLWindow и рисую себе из др нитки. Или это утопия?  Улыбающийся
« Последнее редактирование: Сентябрь 05, 2016, 09:07 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #38 : Сентябрь 05, 2016, 09:19 »

Если так - то вот и решение, создал QOpenGLWindow и рисую себе из др нитки. Или это утопия?  Улыбающийся

Так очень часто и делают).
Записан
Bepec
Гость
« Ответ #39 : Сентябрь 05, 2016, 09:48 »

Да ответ, я думаю, ещё проще.
Когда разрабатывалось первое UI, никто и не думал, что будет необходимость в многопоточном ui. Да и ресурсы ОС выделялись более бережно.
А так как менять эту систему - значит переписать очень много много кода и ещё больше сил потратить на поддержку устаревших программ, то это никому не надо. Так и живём Веселый
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #40 : Сентябрь 05, 2016, 10:04 »

наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)
Да все проще.
Если отвлечься от окон верхнего уровня, которые и так рисуются параллельно разными процессами (правда в буфер), и вспомнить про дочерние виджеты, которые как правило рисует сам процесс (использую GUI-библиотеку). Попробуйте обновлять дочерние виджеты параллельно, особенно если они перекрывают друг-друга. Для правильного отображения все равно придется кому-то одному прорисовывать виджеты в правильном порядке, для организации правильного перекрывания. А сами виджеты легко могут обновлять параллельно в разных потоках, главное что-бы окончательная отрисовка их выполнялась кем-то одним, кто знает в каком порядке их рисовать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #41 : Сентябрь 05, 2016, 10:05 »

Так очень часто и делают).
Никогда об этом не слышал, всегда железное "только в главной!!!" Улыбающийся При случае попробую (ох сомневаюсь все-таки)
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #42 : Сентябрь 05, 2016, 10:11 »

Никогда об этом не слышал, всегда железное "только в главной!!!" Улыбающийся При случае попробую (ох сомневаюсь все-таки)
http://www.gamedev.ru/community/ogl/articles/multithreading
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #43 : Сентябрь 05, 2016, 10:56 »

Да все проще.
Если отвлечься от окон верхнего уровня, которые и так рисуются параллельно разными процессами (правда в буфер), и вспомнить про дочерние виджеты, которые как правило рисует сам процесс (использую GUI-библиотеку). Попробуйте обновлять дочерние виджеты параллельно, особенно если они перекрывают друг-друга. Для правильного отображения все равно придется кому-то одному прорисовывать виджеты в правильном порядке, для организации правильного перекрывания. А сами виджеты легко могут обновлять параллельно в разных потоках, главное что-бы окончательная отрисовка их выполнялась кем-то одним, кто знает в каком порядке их рисовать.

В том то и дело, что подготовку данных для финального отображения (где учитывается и порядок, и много чего еще - эффекты, текстуры и т.п.) можно совершенно параллельно, да и обрабатывать события GUI и др. можно независимо от финальной процедуры отображения. Улыбающийся И формально только реализованная в Qt стратегия обработки событий накладывает ограничения на принадлежность всего дерева Widget одному и тому же потоку.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #44 : Сентябрь 05, 2016, 11:02 »

И формально только реализованная в Qt стратегия обработки событий накладывает ограничения на принадлежность всего дерева Widget одному и тому же потоку.
Да ничего она не накладывает. Можно рисовать хоть все виджеты сцены, каждый в своем потоке, правда рисовать придется в буфер (QImage). А вот окончательное рисование придется выполнять в paintEvent. Вот как раз метод paintEvent и вызывает тот самый, кто-знает порядок отрасивки всех виджетов и без кторого нормально сцену не построить.
« Последнее редактирование: Сентябрь 05, 2016, 11:07 от Old » Записан
Страниц: 1 2 [3] 4 5   Вверх
  Печать  
 
Перейти в:  


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