| 
 Название: [РЕШЕНО] 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(). Там то и указывается сколько максимально потоков может быть задействованно и другие параметры. 
 
 |