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

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

Страниц: 1 2 [3] 4 5 6   Вниз
  Печать  
Автор Тема: Создание/вызов методов в разных потоках.  (Прочитано 45215 раз)
zenden
Гость
« Ответ #30 : Ноябрь 29, 2009, 02:10 »

Цитата: Павел_F
Я вот обдумал все, представил себя пользователем и пришел к выводу что я не могу смотреть в два разных ГУЯ одновременно.

Вы сначала ознакомились лучше бы ознакомились с сутью вопроса, прежде чем выдавать такие перлы.
Записан
spectre71
Гость
« Ответ #31 : Ноябрь 29, 2009, 02:13 »

Вот вы тут спорите про потоки... И ГУЙ в разных потоках... Я вот обдумал все, представил себя пользователем и пришел к выводу что я не могу смотреть в два разных ГУЯ одновременно. Только по очереди. А раз пользователь не может то зачем это реализовывать программисту? Тем более что это сложно реализовать. Ведь любая программа рассчитана на некоего пользователя. И я считаю это весьма логичным, даже не вдаваясь в потокобезопасность и прочее( хоть и имею представление об этом). Так что один пользователь смотрит в один ГУЙ, а что и когда появится в этом ГУЕ это уже дело программиста. И если у последнего возникает надобность в двух ГУЯх одновременно то что-то он напутал в разработке интерфейса.

Ты хоть сам понял что написал.
Записан
Павел_F.
Гость
« Ответ #32 : Ноябрь 29, 2009, 02:22 »

Понял, может не верно изложил. Во всей теме спорят про "теорию вопроса". Практического же увидел только "QWebView в цикле", инет браузер и намек на надобность показать окошко по событию из другого потока. Во всех этих задачах я не вижу смысла делать графический интерфейс в нескольких потоках. А зечем спорить почему этого нет и придумывать как это сделать если это не надо?
Записан
spectre71
Гость
« Ответ #33 : Ноябрь 29, 2009, 02:59 »

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

- Поскольку в OS одновременно работают много процессов, в том числе и имеющих графический интерфейс, то на уровне OS такой проблемы нет. Система сама устанавливает блокировки при обращении к ее определенным ресурсам, в том числе и к графическим контекстам! Так что проблема только на уровне библиотеки.
- По поводу накладности Mutex , для данного случая - абсолютно не согласен. Не тот случай!
  a) Операция прерисовки относительно редкая.
  b) Очень длительная операция по сравнению со временем создания блокировки - отношение много порядков

И к слову. Реализация Mutex в QT сделана не хорошо. Нормальный Mutex предполагает Spin Count(покрутиться заданное колличество раз 1000-100000 на атомарной операции в ожидании разблокировки прежде чем усыпить поток)! Таким образом, QT-й Mutex не позволяет без больших накладных расходов использовать его для межпоточной защиты очень частых, но очень коротких по времени последовательностей операций.
 
====
Дока QT - это нечто! Я не верю что накосячили в переводе. Постоянно встречаю такие приколы!

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

Это как понимать!
Да так и понимать: они крутят EventLoop для каждой нитки. А обработчик объекта обычно делает "что-то сверху" и отдается на обработчик парента - а событие-то было послано в другом loop. Лучше сначала разобраться а потом горячиться  Улыбающийся

Перечитал в оригинале, понял прикол. Речь об отношении включения(родитель-дочерний объект), а не о наследовании. Улыбающийся
Цитировать
The child of a QObject must always be created in the thread where the parent was created.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #34 : Ноябрь 29, 2009, 03:13 »

>>а не о наследовании
да, надо будет поправить, "потомка" на "дочерний", а "предка" на "родительский". В новых переводах так и договорились делать. А то двояко звучит
Записан

Юра.
spectre71
Гость
« Ответ #35 : Ноябрь 29, 2009, 03:14 »

Понял, может не верно изложил. Во всей теме спорят про "теорию вопроса". Практического же увидел только "QWebView в цикле", инет браузер и намек на надобность показать окошко по событию из другого потока. Во всех этих задачах я не вижу смысла делать графический интерфейс в нескольких потоках. А зечем спорить почему этого нет и придумывать как это сделать если это не надо?

Пример с тем же QWebView, насколько я понял он грузит данные в другом потоке. Но вот отрисовку он делает естественно в главном.
И я заметил(я это протестировал), если ему подать что-то очень тяжелое для отображения, то он замораживает интерфейс на некоторое время. Сам ощутил замараживание секунд на 5! Очень неприятно. А вот если бы можно было рисовать в другом потоке, то этого бы не происходило
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #36 : Ноябрь 29, 2009, 03:16 »

>>если бы можно было рисовать в другом потоке, то этого бы не происходило
рисовать можно в другом потоке, рисуй на QImage, а в главном копируй его.
Записан

Юра.
spectre71
Гость
« Ответ #37 : Ноябрь 29, 2009, 03:26 »

>>если бы можно было рисовать в другом потоке, то этого бы не происходило
рисовать можно в другом потоке, рисуй на QImage, а в главном копируй его.

Ты уверен? Вроде painter это не позволяет???

Даже если это так, то ты не заставишь это делать тот-же QWebView!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

- Поскольку в OS одновременно работают много процессов, в том числе и имеющих графический интерфейс, то на уровне OS такой проблемы нет. Система сама устанавливает блокировки при обращении к ее определенным ресурсам, в том числе и к графическим контекстам! Так что проблема только на уровне библиотеки.
Не путайте, OS никакой защиты не имеет, попробуйте painter.begin() без painter.end() или создавать QPainter не на стеке - и получите неприятности очень быстро. Для многих процессов OS просто проталкивает их последовательно но это не прокатит с 2 и более нитками 1 процесса.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



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

Но один вопрос остается без ответа: Почему ГУИ объекты нельзя создавать в потоке? Где об этом можно почитать? Может какой костыль написать? Смеющийся

имхо, это ограничение библиотеки и никакой костыль ненапишешь. Нестоит забывать, что Qt это кросплатформенный фреймворк, и, возможно, не все ОС поддерживают несколько GUI потоков в пределах процесса. Например, винда поддерживает несколько GUI потоков.

По потокам и процессам можно почитать в очень неплохой книге:

Джеффри Рихтер. Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

а именно главы 6, 26, 27.
« Последнее редактирование: Ноябрь 29, 2009, 13:28 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #40 : Ноябрь 29, 2009, 05:35 »

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

Нитак. thread-save != reentrant

Функции, которые можно одновременно вызывать из разных потоков - tread safe. Если в классе все функции такие, то и класс называется tread safe. reentrant - функции, которые можно безопастно вызывать для одного и того же екземпляра класса только из одного потока - в котором он был создан.

Подробнее читаем в ассистанте - Thread Support in Qt
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


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

>>Ты уверен? Вроде painter это не позволяет???
для QImage можно, он специально создан для использования в разных потоках
Записан

Юра.
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #42 : Ноябрь 29, 2009, 05:43 »

Ты уверен? Вроде painter это не позволяет???

QImage Class Reference

Цитировать
Because QImage is a QPaintDevice subclass, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread.

The Paint System

Цитировать
One advantage of using QImage as a paint device is that it is possible to guarantee the pixel exactness of any drawing operation in a platform-independent way. Another benefit is that the painting can be performed in another thread than the current GUI thread.


Иногда полезно заглядывать в ассистант.
« Последнее редактирование: Ноябрь 29, 2009, 05:45 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



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

Вот вы тут спорите про потоки... И ГУЙ в разных потоках... Я вот обдумал все, представил себя пользователем и пришел к выводу что я не могу смотреть в два разных ГУЯ одновременно. Только по очереди.
Дело в том, что изначально речь шла не столько о ГУЕ, сколько о qwebview в частности. Задача (например в моём случае) состоит в том, чтобы эмитировать работу "нескольких браузеров" одновременно, вот и всё. Выводить на экран ничего не нужно, главное чтобы была прорисовка js, html, css, etc. "за кулисами". Т.е. тут, несмотря на то, что метод загрузки url'a load() асинхронный - этого мало. Будут "переходы" на другие сайты, поиск текста по страницам, все эти методы асинхронными не будут, чтобы делать всё в одном потоке.
Тут уже был дан вариант решения - слать сигнал на главный поток, чтобы он создал экземпляр qwebview и возвращал его назад в поток. Тут у меня один вопрос (наверное, ввиду моей неопытности при работе с сигналами/слотами): как указать слот, чтобы сигнал типа qwebview слался в run() дочернего потока??
Пробовал как вариант:
Код:
class RunThreads extends QSignalEmitter implements Runnable
{
 //сигнал для главного потока, для создания qwebview
 public Signal1<Integer> signalOut2 = new Signal1<Integer>();
 //в слоте этого класса назначу этой переменной отосланный главным потоком qwebview
 QWebView wv;
 QUrl url = new QUrl("http://2ip.ru/");

 RunThreads(Ui_Form form, int thCount)
 {
  //количество создаваемых qwebview
  _thCount = thCount;
 }

 public void run()
 {
  for (int i = 0; i <= _thCount; i ++)
  {
   //при получении ответа от главного потока использовать объект QWebView в методе xxx2() этого класса
   _form.signalOut1.connect(this, "xxx2(QWebView)", ConnectionType.QueuedConnection);
   //испустить сигнал, чтобы главный поток создал экземпляр QWebView
   this.signalOut2.emit(1);

   //QWebView всё равно не загружается, выдаёт ошибку о разных потоках
   this.wv.load(this.url);
  }
 }

 public void xxx2(QWebView v)
 {
  this.wv = v;
 }
Тут код очень урезанный, его цель - просто использовать в другом потоке qwebview - пока всё. Если это заработает, другие вещи не проблема.
п.с. сил больше нет бороться с этим qwebview((


« Последнее редактирование: Ноябрь 29, 2009, 14:18 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
BRE
Гость
« Ответ #44 : Ноябрь 29, 2009, 14:30 »

п.с. сил больше нет бороться с этим qwebview((
Я это уже предлагал, но повторюсь.
А ты не пробовал использовать вместо QWebView объекты классов QWebPage/QWebFrame.
Это не GUI-классы и думаю спокойно смогут работать в других потоках.
Записан
Страниц: 1 2 [3] 4 5 6   Вверх
  Печать  
 
Перейти в:  


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