Название: [РЕШЕНО] QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: gil9red от Сентябрь 09, 2012, 19:59
Здравствуйте! :) Использую QFuture и QtConcurrent для того чтобы функция выполнялась в отдельном потоке и не нагружала главный Написал тестовый вариант на основе примера QtConcurrent Run Function Example: #include <QDebug> #include <QThread> #include <QString> #include <QtConcurrentRun> #include <QFuture> #include <QApplication>
class foo { public: foo(QString str) { QtConcurrent::run(this, &foo::msg, str); } private: void msg(QString name) { qDebug() << "Hello" << name << "from" << QThread::currentThread(); } };
int main(int argc, char **argv) { QApplication app(argc, argv);
foo("Hello World!"); foo("Hello C++!"); foo("Hello Qt!");
app.exec(); }
только вот после выполнения не остается всего 1 поток - главный а весят 4 смотря в документацию изменил конструктор: foo(QString str) { QFuture <void> threadFunc = QtConcurrent::run(this, &foo::msg, str); threadFunc.waitForFinished(); threadFunc.cancel(); }
но не все созданные потоки можно закрыть (остаются не закрытыми 2: главный и созданный run), о чем, если я не ошибаюсь написанно в документации в программе могут использоваться множество раз одни и теже функции: void Note::loadDataNote() { QSettings settingsINI(pathIni, QSettings::IniFormat);
settingsINI.setIniCodec(QTextCodec::codecForName("windows-1251"));
dataNote.globalPosX = settingsINI.value("GlobalPosX", 100).toInt(); dataNote.globalPosY = settingsINI.value("GlobalPosY", 100).toInt(); dataNote.width = settingsINI.value("Width", 200).toInt(); dataNote.height = settingsINI.value("Height", 200).toInt(); dataNote.title = settingsINI.value("Title", "").toString(); dataNote.lock = settingsINI.value("Lock", false).toBool(); dataNote.text = settingsINI.value("Text", "").toString(); dataNote.visible = settingsINI.value("Visible", true).toBool(); dataNote.opacityNote = settingsINI.value("Opacity", 100).toFloat() / 100; dataNote.colorNote = con.getColorFromHexColorForStyleSheet(color); dataNote.attribute = settingsINI.value("Attribute", "Default").toString(); dataNote.dateOfCreating = settingsINI.value("DateOfCreating", date).toString(); dataNote.dateLastChange = settingsINI.value("DateLastChange", date).toString(); dataNote.countTextSymbols = settingsINI.value("CountTextSymbols", 0).toInt(); dataNote.countTextLines = settingsINI.value("CountTextLines", 1).toInt(); dataNote.password = settingsINI.value("Password/Password", "").toString(); dataNote.protectionActive = settingsINI.value("Password/protectionActive", false).toBool(); }
void Note::saveDataNote() { QSettings settingsINI(pathIni, QSettings::IniFormat);
settingsINI.setIniCodec(QTextCodec::codecForName("windows-1251"));
settingsINI.setValue("GlobalPosX", dataNote.globalPosX); settingsINI.setValue("GlobalPosY", dataNote.globalPosY); settingsINI.setValue("Width", dataNote.width); settingsINI.setValue("Height", dataNote.height); settingsINI.setValue("Title", dataNote.title); settingsINI.setValue("Lock", dataNote.lock); settingsINI.setValue("Text", dataNote.text); settingsINI.setValue("Visible", dataNote.visible); settingsINI.setValue("Opacity", int(dataNote.opacityNote * 100)); settingsINI.setValue("Color", color); settingsINI.setValue("Attribute", dataNote.attribute); settingsINI.setValue("DateOfCreating", dataNote.dateOfCreating); settingsINI.setValue("DateLastChange", dataNote.dateLastChange); settingsINI.setValue("CountTextSymbols", dataNote.countTextSymbols); settingsINI.setValue("CountTextLines", dataNote.countTextLines); settingsINI.setValue("Password/Password", dataNote.password); settingsINI.setValue("Password/protectionActive", dataNote.protectionActive);
settingsINI.sync(); }
их я и хочу засунуть в потоки, и было бы не красиво иметь в процессе программы несколько сотен потоков как правильно запустить функцию в отдельном потоке, и после выполнения функции закрыть поток? :)
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: mutineer от Сентябрь 09, 2012, 20:02
Зачем закрывать? QtConcurrent следущую функцию запустит в одном из уже имеющихся потоков, чем сократит издержки на многократный запуск/остановку потоков
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: gil9red от Сентябрь 09, 2012, 20:09
Значит threadFunc.waitForFinished(); threadFunc.cancel();
вызов функции в созданном потоке, если предыдущая функция завершилась или создание нового потока?
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: mutineer от Сентябрь 09, 2012, 20:16
Значит threadFunc.waitForFinished(); threadFunc.cancel();
вызов функции в созданном потоке, если предыдущая функция завершилась или создание нового потока? Эти две строки имеют мало смысла - пытаться остановить вычисление тогда, когда оно уже остановилось это очень странно Ну и даже если ты поменяешь их местами, то: the future returned by QtConcurrent::run() cannot be canceled
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: gil9red от Сентябрь 09, 2012, 20:38
не без этих строчек количество поток с каждым вызовом run будет расти
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: mutineer от Сентябрь 09, 2012, 20:39
не без этих строчек количество поток с каждым вызовом run будет расти
Ты пробовал? создай три задания, подожди пока они выполнятся, а потом задай еще 2-3. Сколько потоков будет?
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: gil9red от Сентябрь 09, 2012, 21:06
Вроде разобрался=) не без этих строчек количество поток с каждым вызовом run будет расти
Ты пробовал? создай три задания, подожди пока они выполнятся, а потом задай еще 2-3. Сколько потоков будет? 1. Без строчек: QFuture <void> threadFunc = QtConcurrent::run(this, &foo::msg, str); threadFunc.waitForFinished(); threadFunc.cancel();
и с 3 заданиями создаваться + 3 потока, если после выполнения этих трех заданий добавить, например + 2 задания, то они будут выполняться, но не будут создавать новые потоки 2. С строками: QFuture <void> threadFunc = QtConcurrent::run(this, &foo::msg, str); threadFunc.waitForFinished(); threadFunc.cancel();
и с 3 заданиями создаваться + 1 поток, если после выполнения этих трех заданий добавить, например + 2 задания, то они будут выполняться, но не будут создавать новые потоки код: #include <QDebug> #include <QThread> #include <QString> #include <QtConcurrentRun> #include <QFuture> #include <QApplication> #include <QtGui>
class SleeperThread : public QThread { public: static void msleep(unsigned long msecs) { QThread::msleep(msecs); } };
class foo { public: foo(QString str) { QFuture <void> threadFunc = QtConcurrent::run(this, &foo::msg, str); threadFunc.waitForFinished(); threadFunc.cancel(); } private: void msg(QString name) { qDebug() << "Hello" << name << "from" << QThread::currentThread(); } };
void main(int argc, char **argv) { QApplication app(argc, argv);
foo("Hello World!"); foo("Hello C++!"); foo("Hello Qt!");
SleeperThread::msleep(3000);
foo("1"); foo("2");
app.exec(); }
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: mutineer от Сентябрь 10, 2012, 01:07
Магия этих твоих двух строк (точнее одной - waitForFinished) в том, что код ждет выполнения текущего задания, прежде чем дать следующее. А раз задания выполняются точно одно за одним, то им достаточно одного дополнительного потока. Если завершения не ждать, то несколько заданий будут выполняться одновременно и им уже нужно больше потоков
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: gil9red от Сентябрь 10, 2012, 20:50
Ок :) ;D
Название: Re: QFuture и QtConcurrent удаление потока после завершения фукнции
Отправлено: fuCtor от Сентябрь 16, 2012, 16:15
QtConcurrent использует для выполнения пул потов, который можно получить через QThreadPool::globaInstance(). Там то и указывается сколько максимально потоков может быть задействованно и другие параметры.
|