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

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

Страниц: 1 [2] 3 4 ... 6   Вниз
  Печать  
Автор Тема: Создание/вызов методов в разных потоках.  (Прочитано 44833 раз)
niXman
Гость
« Ответ #15 : Ноябрь 28, 2009, 21:08 »

Spectre
Спасибо. Изучаю вашу тему по ссылке.

Igors
Вынужден согласиться. Так как написание правильного алгоритма, займет меньше времени чем ковыряние поднаготной Qt Подмигивающий
Записан
BRE
Гость
« Ответ #16 : Ноябрь 28, 2009, 22:38 »

Так как написание правильного алгоритма, займет меньше времени чем ковыряние поднаготной Qt Подмигивающий
Да это скорее не ограничение Qt, а ограничение любого графического интерфейса.

Экран - это ресурс, доступ к которому должен быть синхронным. Если один поток начнет перерисовывать виджет и на середине будет прерван, управление получит другой поток, который также захочет перерисовать другой виджет на экран, а эти виджеты перекрывают друг друга, то проблемы неизбежны.

Также при сложных интерфейсах (в которых виджеты могут перекрывать друг друга) необходима оптимизация обновляемых регионов. Например, перерисовывается виджет нижнего уровня, который на 90% перекрыт виджетами верхнего уровня, то целесообразно перерисовывать только видимую часть (10%) этого виждета. Такая оптимизация возможна только если рисование всего происходит в одном месте (главном потоке, например).
Записан
spectre71
Гость
« Ответ #17 : Ноябрь 28, 2009, 23:29 »

Так как написание правильного алгоритма, займет меньше времени чем ковыряние поднаготной Qt Подмигивающий
Да это скорее не ограничение Qt, а ограничение любого графического интерфейса.

Пункт 1
Экран - это ресурс, доступ к которому должен быть синхронным. Если один поток начнет перерисовывать виджет и на середине будет прерван, управление получит другой поток, который также захочет перерисовать другой виджет на экран, а эти виджеты перекрывают друг друга, то проблемы неизбежны.

Пункт 2
Также при сложных интерфейсах (в которых виджеты могут перекрывать друг друга) необходима оптимизация обновляемых регионов. Например, перерисовывается виджет нижнего уровня, который на 90% перекрыт виджетами верхнего уровня, то целесообразно перерисовывать только видимую часть (10%) этого виждета. Такая оптимизация возможна только если рисование всего происходит в одном месте (главном потоке, например).

Не согласен

Пункт 1
Это обеспечивается операционкой, поскольку существует множество GUI процессов. И если бы это было так как ты написал, то проблема была бы на уровне главных потоков этих процессов.

Пункт 2
Примем:
Виджеты 1-го уровеня виджеты не прекрываемые другими виджетами и не содежащие другие виджеты
Виджеты 2-го уровня - могут содержать только виджеты 1-го уровеня или быть ими пререкрыты
Итд..

1 вариант) Пререрисовка в главном потоке.
Имеем виджет 2 уровня который перересовываем, соответственно виджеты 1-го уровня пресекающиеся с ним - будут ли они перерисовываться? - НЕТ. Прересовываятся только видимые регионы.
2 вариант) Пререрисовка в разных потоках.
Все тоже самое как и в пункте 1. Разница только в том что для получения регионов виджета(их несколько из-за перекрытий) требующих перерисовки может потребоваться Mutex




Предположим имеем виджет 2 уровня
Записан
BRE
Гость
« Ответ #18 : Ноябрь 28, 2009, 23:38 »

Пункт 1
Это обеспечивается операционкой, поскольку существует множество GUI процессов. И если бы это было так как ты написал, то проблема была бы на уровне главных потоков этих процессов.
Что обеспечивается операционкой?
В Qt операционка управляет только виджетами верхнего уровня. Все внутренние отрисовки производит сама Qt. Но не суть важно.
Операционка точно также перехватывает события PAINT и сама определяет момент перерисовки на экран. И делает она это в один момент для всех окон всех приложений.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #19 : Ноябрь 28, 2009, 23:45 »

Есть такие страшные слова:
Потокобезопасность
реентерабельность
Есть достаточно много людей которые с этими понятиями парятся и до конца их не понимают (я один из них).

Дак вот если ещё QWidget'ы сделать со всякой там реентерабельностью, то телефон службы техподдержки трольтеха отключила бы телефонная компания.

В Асистенте сказано:
Цитировать
Несмотря на то, что QObject реентерабелен, классы ГПИ, особенно QWidget и все его подклассы, таковыми не являются. Они могут использоваться только из главного потока.
...
На практике невозможно использовать классы ГПИ в других потоках, кроме главного, но выполнение продолжительных действий можно легко поместить в отдельный поток и отображать на экране результаты выполнения средствами главного потока по окончании обработки во вспомогательном потоке.
тыц
« Последнее редактирование: Ноябрь 28, 2009, 23:47 от lit-uriy » Записан

Юра.
spectre71
Гость
« Ответ #20 : Ноябрь 28, 2009, 23:47 »

Пункт 1
Это обеспечивается операционкой, поскольку существует множество GUI процессов. И если бы это было так как ты написал, то проблема была бы на уровне главных потоков этих процессов.
Что обеспечивается операционкой?
В Qt операционка управляет только виджетами верхнего уровня. Все внутренние отрисовки производит сама Qt. Но не суть важно.
Операционка точно также перехватывает события PAINT и сама определяет момент перерисовки на экран. И делает она это в один момент для всех окон всех приложений.


Ну а где противоречие с тем что я написал выше? Ты говорил что это не проблема библиотек и привел аргументы, я привел тебе примеры.
Не спорю, вполне вожможно что операционка делает перерисовку окон синхронно(синхронизированно) для разных процессов(их главных потоков) и это пример того что это возможно! => ничто не мешает сделать необходимую синхронизацию при отрисовки виджетов на уровне библиотеки!
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #21 : Ноябрь 28, 2009, 23:48 »

там же, по ссылке, указаны и причины
Записан

Юра.
BRE
Гость
« Ответ #22 : Ноябрь 28, 2009, 23:53 »

ничто не мешает сделать необходимую синхронизацию при отрисовки виджетов на уровне библиотеки!
Да сделать то все можно, только для чего, в чем будет выигрыш? Если все сведется к одному потоку, который и будет все отрисовывать.
Что даст эта возможность, кроме усложнения (и наверняка) замедлению библиотеки?

Наверное, поэтому это и не было сделано.
Записан
spectre71
Гость
« Ответ #23 : Ноябрь 29, 2009, 00:11 »

там же, по ссылке, указаны и причины

Абсолютно не связанные вещи, речь шла о проблемах пререисовки и что якобы это не ограничения библиотеки, с чем я не согласен!
На мой взгляд это именно ограничения библиотеки.
Записан
spectre71
Гость
« Ответ #24 : Ноябрь 29, 2009, 00:15 »

ничто не мешает сделать необходимую синхронизацию при отрисовки виджетов на уровне библиотеки!
Да сделать то все можно, только для чего, в чем будет выигрыш? Если все сведется к одному потоку, который и будет все отрисовывать.
Что даст эта возможность, кроме усложнения (и наверняка) замедлению библиотеки?

Наверное, поэтому это и не было сделано.

Мы говорили именно о перерисовке.
Выигрыш в том что удобнее использовать, я поскольку перерисовка делается, относительно медленно, то thread-save (через Mutex) не даст замедления.
Записан
BRE
Гость
« Ответ #25 : Ноябрь 29, 2009, 00:21 »

На мой взгляд это именно ограничения библиотеки.
Давай посмотрим на несколько моментов. Например:
В одном потоке (1) создается окно, в другом потоке (2) создается виджет, который должен располагаться на этом окне. На примере Qt, parent'ом для этого виджета нужно указать окно из потока 1. Поток 2 начинает что-то делать со своим виджетом, в середине работы происходит переключение на поток 1, который решает разрушить окно. Что делать библиотеке? Убить виджет вместе с окном, но тогда при переключении на поток 2 (где идет работа с этим виджетом) все ляжет. Отвязать этот виджет и не трогать, тогда кто будет удалять виджет и что с ним вообще дальше делать?
Записан
spectre71
Гость
« Ответ #26 : Ноябрь 29, 2009, 00:42 »

Есть такие страшные слова:
Потокобезопасность
реентерабельность

Есть достаточно много людей которые с этими понятиями парятся и до конца их не понимают (я один из них).
По поводу реентерабельности, вот почитай:
Реентерабельность

Короче это thread-save "Реентерабельность" для функций.
Для объекта thread-save:
- Все методы - реентерабельны
- нет непосредственного(не через методы) доступа к данным объекта
Вроде так

Дак вот если ещё QWidget'ы сделать со всякой там реентерабельностью, то телефон службы техподдержки трольтеха отключила бы телефонная компания.

В Асистенте сказано:
Цитировать
Несмотря на то, что QObject реентерабелен, классы ГПИ, особенно QWidget и все его подклассы, таковыми не являются. Они могут использоваться только из главного потока.
...
На практике невозможно использовать классы ГПИ в других потоках, кроме главного, но выполнение продолжительных действий можно легко поместить в отдельный поток и отображать на экране результаты выполнения средствами главного потока по окончании обработки во вспомогательном потоке.
тыц

Это связано не только с виджетами, но и с кучей других классов. Я и не спорил о том что виджеты нельзя использовать многопоточно и не в главном потоке.
И  это естественно касается не только создания но и любого использования виджетов(вызова их методов) за пределами главного потока.
Но не понятны причины почему это так. Не thread-save предполагает использование объекта только в одном потоке, но это не занчит что в главном! Про поблемы синхронизации перерисовки я уже писал - это проблема библиотеки. неужели проблема только в этом?

====
Дока QT - это нечто! Я не верю что накосячили в переводе. Постоянно встречаю такие приколы!

Цитировать
    * Потомок QObject должен всегда создаваться в том же потоке, что и предок.

Это как понимать!
Записан
spectre71
Гость
« Ответ #27 : Ноябрь 29, 2009, 00:56 »

На мой взгляд это именно ограничения библиотеки.
Давай посмотрим на несколько моментов. Например:
В одном потоке (1) создается окно, в другом потоке (2) создается виджет, который должен располагаться на этом окне. На примере Qt, parent'ом для этого виджета нужно указать окно из потока 1. Поток 2 начинает что-то делать со своим виджетом, в середине работы происходит переключение на поток 1, который решает разрушить окно. Что делать библиотеке? Убить виджет вместе с окном, но тогда при переключении на поток 2 (где идет работа с этим виджетом) все ляжет. Отвязать этот виджет и не трогать, тогда кто будет удалять виджет и что с ним вообще дальше делать?


Это проблема неправильного использования, неправильной сихронизации, т.е. проблема программиста.
С таким же успехом можно напортачить с любым объектом совместно используемым в нескольких потоках.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Ноябрь 29, 2009, 01:38 »

Но не понятны причины почему это так. Не thread-save предполагает использование объекта только в одном потоке, но это не занчит что в главном! Про поблемы синхронизации перерисовки я уже писал - это проблема библиотеки. неужели проблема только в этом?
Библиотека здесь ни при чем. Представим себе что сейчас OS заполняет/заливает регион каким-то цветом (шлет 5-10Mb в видео). Понятно что если кто-то встрянет с др. рисованием - регион разрушен, crash. Значит надо как-то "держать и не пущать" остальных рисующих. А каким образом если 2 и более ниткам разрешено захватывать контекст, выкладывать окна и.т.п? Все хорошо если несколько процессов рисуют "одновременно" (якобы). OS все равно делает это последовательно (на слабом железе хорошо видно) - сначала пошлет paint/update одному окну/процессу, потом другому (а между этим проверит др. события). А вот если 2 нитки в 1 процессе прутся - как? Ставить мутекс на каждый чих? Не хуже меня знаете - удовольствие слишком дорогое для операций рисования.

====
Дока QT - это нечто! Я не верю что накосячили в переводе. Постоянно встречаю такие приколы!

Цитировать
    * Потомок QObject должен всегда создаваться в том же потоке, что и предок.

Это как понимать!
Да так и понимать: они крутят EventLoop для каждой нитки. А обработчик объекта обычно делает "что-то сверху" и отдается на обработчик парента - а событие-то было послано в другом loop. Лучше сначала разобраться а потом горячиться  Улыбающийся
Записан
Павел_F.
Гость
« Ответ #29 : Ноябрь 29, 2009, 01:59 »

Вот вы тут спорите про потоки... И ГУЙ в разных потоках... Я вот обдумал все, представил себя пользователем и пришел к выводу что я не могу смотреть в два разных ГУЯ одновременно. Только по очереди. А раз пользователь не может то зачем это реализовывать программисту? Тем более что это сложно реализовать. Ведь любая программа рассчитана на некоего пользователя. И я считаю это весьма логичным, даже не вдаваясь в потокобезопасность и прочее( хоть и имею представление об этом). Так что один пользователь смотрит в один ГУЙ, а что и когда появится в этом ГУЕ это уже дело программиста. И если у последнего возникает надобность в двух ГУЯх одновременно то что-то он напутал в разработке интерфейса.
Записан
Страниц: 1 [2] 3 4 ... 6   Вверх
  Печать  
 
Перейти в:  


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