Russian Qt Forum
Ноябрь 22, 2024, 17:49
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Многопоточное программирование, процессы
>
Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке (Прочитано 5178 раз)
r2d2u2
Гость
Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
:
Ноябрь 10, 2010, 01:46 »
В общем есть Объект класса унаследованного от QThread.
Дергаем метод Start() у этого объекта несколько раз подряд.
Исполнение этого метода запускается в отдельном потоке. Несколько раз. Подряд. Причем следующий вызов не ожидает завершения предыдущего.
При этом когда этот метод запускается в то время когда выполняется исполнение предыдущего вызова, !все в том же потоке! то предыдущий вызов никуда не девается а как бы попадает в стек,
и ждет пока завершится последний вызов потом возобновляется.
Вот классы чтобы самим не писать соберите консольное приложение и потыкайте кнопкой несколько раз: у меня вывод вот такой:
ThreadObject::ThreadObject(): 0x9c 0
ThreadObject::run(): 0x4a0 0
ThreadObject::StartTimer(): 0x4a0 0
ThreadObject::StartTimer(): 0x4a0 1
ThreadObject::StartTimer(): 0x4a0 2
ThreadObject::StartTimer(): stop 0x4a0 3
ThreadObject::StartTimer(): stop 0x4a0 3
ThreadObject::StartTimer(): stop 0x4a0 3
class ThreadObject: public QThread
{
Q_OBJECT
public:
ThreadObject();
virtual ~ThreadObject();
public slots:
void Start();
public:
void run();
int Var;
};
ThreadObject::ThreadObject()
{
moveToThread(this);
Var = 0;
qDebug() << "ThreadObject::ThreadObject(): " << currentThreadId() << Var;
}
ThreadObject::~ThreadObject()
{
quit();
wait();
}
void ThreadObject::run()
{
qDebug() << "ThreadObject::run(): " << currentThreadId() << Var;
exec();
}
void ThreadObject::Start()
{
qDebug() << "ThreadObject::StartTimer(): " << currentThreadId() << Var;
++Var;
for (qint64 i = 0; i < 500000; ++i)
{
QCoreApplication::processEvents(QEventLoop::AllEvents, 1);
}
qDebug() << "ThreadObject::StartTimer(): stop" << currentThreadId() << Var;
}
class MyWidget: public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget* parent = 0);
void Create();
void Layout();
void Connect();
void StartThread();
private:
QPushButton* Button;
ThreadObject TheThreadObject;
};
MyWidget::MyWidget(QWidget* parent /*= 0*/)
: QWidget(parent)
{
Create();
Layout();
Connect();
StartThread();
}
void MyWidget::Create()
{
Button = new QPushButton("QPush button");
}
void MyWidget::Layout()
{
QHBoxLayout* mainLayout = new QHBoxLayout();
mainLayout->addWidget(Button);
setLayout(mainLayout);
}
void MyWidget::Connect()
{
connect(Button, SIGNAL(clicked()), &TheThreadObject, SLOT(Start()));
}
void MyWidget::StartThread()
{
TheThreadObject.start();
}
ну и main
int main(int argc, char **argv)
{
setlocale(LC_CTYPE, "");
bool useGUI = true;
QApplication app(argc, argv, useGUI);
MyWidget mWidget;
mWidget.show();
return app.exec();
}
Есть какие либо мысли и соображения?
Если вызвать метод Start() первый раз, начнет выполняться цикл в потоке TH01, и к примеру счетчик i дойдет до 1024.
Потом мы дергаем это метод Start() второй раз, и он запускается снова в потоке TH01! и счетчик начинает считать снова с нуля.
НО!
когда после второго вызова счетчик доходит до предела, выход из метода не происход а возобновляется работа счетчика запущенного при вызове метода в первый раз, т.ею начинается дальше счет с 1024.
Кто нить может объяснить как такое может быть? ) Понятное дело что там в теле цикла стоит вызов QCoreApplication::processEvents(QEventLoop::AllEvents, 1); который обеспечивает обработку событий в том числе обрабатывает обработку события на второй вызов этого метода Start() в то время как предыдущий вызов еще не завершился. Но как смешивается работа циклов непонятно такое ощущение, что при следующем вызове, текущий цикл помещается куда то в стек откуда потом вытаскивается.
кстати QCoreApplication::processEvents(QEventLoop::AllEvents, 1); вызывается внутри функции void QTest::qWait ( int ms ), так что если вы вставите себе этот qWait в теле функции f()работающей в отдельном потоке то при вызове qWait внутри f() она пропусти все события-вызовы f() и ваша f() вызовится несколько раз в одном потоке, и если так мьютекс был рекурсивный то беда! _
Записан
BlackTass
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #1 :
Ноябрь 10, 2010, 02:14 »
По моему все вполне логично
метод запускается еще раз с начала во время процессЕвентс. Когда он доходит до конца процессЕвентс возвращается к выполнению предыдущего запуска этого метода (из которого был вызван этот самый процессЕвентс)
Записан
DmP
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #2 :
Ноябрь 10, 2010, 12:05 »
Цитата: r2d2u2 от Ноябрь 10, 2010, 01:46
В общем есть Объект класса унаследованного от QThread.
Дергаем метод Start() у этого объекта несколько раз подряд.
Зачем его дергать несколько раз подряд?
Цитата: r2d2u2 от Ноябрь 10, 2010, 01:46
Исполнение этого метода запускается в отдельном потоке. Несколько раз. Подряд. Причем следующий вызов не ожидает завершения предыдущего.
В отдельном ли?
Записан
r2d2u2
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #3 :
Ноябрь 10, 2010, 20:01 »
Цитата: BlackTass от Ноябрь 10, 2010, 02:14
По моему все вполне логично
метод запускается еще раз с начала во время процессЕвентс. Когда он доходит до конца процессЕвентс возвращается к выполнению предыдущего запуска этого метода (из которого был вызван этот самый процессЕвентс)
вообщето да, получается вроде рекурсивного вызова себя самой только почему переменная Var как бы разделяется всеми рекурсивными вызовами и увеличивается при каждом вызове а цикл начинается с начала.
Записан
r2d2u2
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #4 :
Ноябрь 10, 2010, 20:12 »
Цитата: DmP от Ноябрь 10, 2010, 12:05
Цитата: r2d2u2 от Ноябрь 10, 2010, 01:46
В общем есть Объект класса унаследованного от QThread.
Дергаем метод Start() у этого объекта несколько раз подряд.
Зачем его дергать несколько раз подряд?
Цитата: r2d2u2 от Ноябрь 10, 2010, 01:46
Исполнение этого метода запускается в отдельном потоке. Несколько раз. Подряд. Причем следующий вызов не ожидает завершения предыдущего.
В отдельном ли?
Зачем дергать несколько раз подряд? Ну к примеру эта функция вызывается другими потоками и может так получится что она вызовется несколько раз подряд. Это в общем на конкретные названия и смысл смотреть не нужно. Это пример.
А запускается действительно в отдельном. Я и сам не пойму почему так получается. Если в конструкторе ThreadObject() вызвать moveToThread(this); то вызов ThreadObject::Start() запускается в отельном потоке. Если в конструкторе не вызывать moveToThread(this) то вызов ThreadObject::Start() запускается в том же потоке откуда вызывается. Вот тоже непонятно почему?
Допустим конструктор ThreadObject() вызывается в главном потоке, и сам объект ThreadObject принадлежит главному потоку, и если в конструкторе вызвать moveToThread(this); то по идее это есть "перемещение" объекта ThreadObject в свой же главный поток. т.е. обработка событий по вызову слотов этого объекта будет осуществляться в главном потоке, по идее смысла от этого нет никакого как мне кажется, но после этого методы объекта ThreadObject вызываются в созданном этим объектом потоке. Вот как понять?
Записан
BRE
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #5 :
Ноябрь 10, 2010, 20:21 »
А ты по форуму поищи темы по moveToThread, уже несколько раз обсуждали, что делает вышеуказанная конструкция и про типы connect, и про очереди сообщений...
Записан
DmP
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #6 :
Ноябрь 10, 2010, 20:42 »
Цитата: r2d2u2 от Ноябрь 10, 2010, 20:12
А запускается действительно в отдельном. Я и сам не пойму почему так получается. Если в конструкторе ThreadObject() вызвать moveToThread(this); то вызов ThreadObject::Start() запускается в отельном потоке. Если в конструкторе не вызывать moveToThread(this) то вызов ThreadObject::Start() запускается в том же потоке откуда вызывается. Вот тоже непонятно почему?
Допустим конструктор ThreadObject() вызывается в главном потоке, и сам объект ThreadObject принадлежит главному потоку, и если в конструкторе вызвать moveToThread(this); то по идее это есть "перемещение" объекта ThreadObject в свой же главный поток. т.е. обработка событий по вызову слотов этого объекта будет осуществляться в главном потоке, по идее смысла от этого нет никакого как мне кажется, но после этого методы объекта ThreadObject вызываются в созданном этим объектом потоке. Вот как понять?
На самом деле тут все просто.
moveToThread(this) - приписывает объект потока в обработчик потока (как и говорится в документации).
При каждом нажатии на кнопку, сигнал помещается в очередь обработчика потока (а не вызывается напрямую, так как потоки разные).
Первый раз ThreadObject::Start() вызывается обработчиком событий потока, который запущен в void ThreadObject::run() через exec().
Все последующие разы ThreadObject::Start() вызывает сам себя, передавая управление обработчику событий через QCoreApplication::processEvents().
Записан
r2d2u2
Гость
Re: Объясните! ) Как тело функции запускается несколько раз в одном и том же потоке
«
Ответ #7 :
Ноябрь 10, 2010, 22:08 »
DmP сапасиба!
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...