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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Аварийное завершение программы при использованиии Concurrent API  (Прочитано 20297 раз)
AlekseyK
Гость
« Ответ #15 : Апрель 16, 2010, 13:34 »

Пример

В Вашем примере функция статическая - в моём случае неприменима, т.к. она требует кучу нестатических членов-переменных класса.
Записан
Kolobok
Гость
« Ответ #16 : Апрель 16, 2010, 13:39 »

Подружить QtConcurrentMap с нестатическим методом у меня так и не получилось.
Записан
AlekseyK
Гость
« Ответ #17 : Апрель 16, 2010, 13:43 »

Параметр в MyMethod объявил, а передать в mapped забыл.

Код
C++ (Qt)
QtConcurrent::mapped(vector,  &MyClass::MyMethod, arg)
 

Как это забыл?! Как его передать? Там нет подобного вызова mapped, есть 2 варианта:
Цитировать
QFuture<T>   mapped ( const Sequence & sequence, MapFunction function )
QFuture<T>   mapped ( ConstIterator begin, ConstIterator end, MapFunction function )

Использую первый.

В примерах из документации Qt, например progressdialog, в mapped больше ничего не передаётся:
Цитировать
void spin(int &iteration)
 {
    ...
}

 int main(int argc, char **argv)
 {
     ...
     // Prepare the vector.
     QVector<int> vector;
     for (int i = 0; i < iterations; ++i)
         vector.append(i);

     // Create a progress dialog.
....
     // Create a QFutureWatcher and conncect signals and slots.
     QFutureWatcher<void> futureWatcher;
....
     // Start the computation.
     futureWatcher.setFuture(QtConcurrent::map(vector, spin));
....
}
Записан
AlekseyK
Гость
« Ответ #18 : Апрель 16, 2010, 13:46 »

Подружить QtConcurrentMap с нестатическим методом у меня так и не получилось.

Вот то-то ж и оно! Придётся видимо использовать QThread. Думал, что Qt действительно что-то изобрело путное для многопоточности, ан нет - те же костыли и проблемы, что и при обыкновенном процедурном программировании: главная проблема - как передать кучу данных потоку и сделать это по возможности красиво Подмигивающий
Записан
Kolobok
Гость
« Ответ #19 : Апрель 16, 2010, 14:06 »

Попробуй вместо mapped использовать blockingMappedReduced. Судя по описанию, должно работать. Только медленно.
Записан
AlekseyK
Гость
« Ответ #20 : Апрель 16, 2010, 14:35 »

Попробуй вместо mapped использовать blockingMappedReduced. Судя по описанию, должно работать. Только медленно.
Попробую, а почему медленно?
Записан
SABROG
Гость
« Ответ #21 : Апрель 16, 2010, 14:57 »

Вот то-то ж и оно! Придётся видимо использовать QThread. Думал, что Qt действительно что-то изобрело путное для многопоточности, ан нет - те же костыли и проблемы, что и при обыкновенном процедурном программировании: главная проблема - как передать кучу данных потоку и сделать это по возможности красиво Подмигивающий

Используй boost::bind, std::tr1::bind или std::bind1st + std::mem_fun

Код
C++ (Qt)
#include <QtCore/QtConcurrentMap>
#include <functional>
 
QString MyClass::myMethod(int arg)
{
...
}
...
QtConcurrent::mapped(vector, std::bind1st(std::mem_fun(&MyClass::myMethod), this));
 
« Последнее редактирование: Апрель 16, 2010, 16:03 от SABROG » Записан
Kolobok
Гость
« Ответ #22 : Апрель 16, 2010, 15:09 »

Попробую, а почему медленно?

Потому что blocking Улыбающийся
Записан
AlekseyK
Гость
« Ответ #23 : Апрель 16, 2010, 15:55 »

Вот то-то ж и оно! Придётся видимо использовать QThread. Думал, что Qt действительно что-то изобрело путное для многопоточности, ан нет - те же костыли и проблемы, что и при обыкновенном процедурном программировании: главная проблема - как передать кучу данных потоку и сделать это по возможности красиво Подмигивающий

Используй boost::bind или std::tr1::bind.

В смысле? Для чего использовать? Для потоков или для mapped?
Записан
SABROG
Гость
« Ответ #24 : Апрель 16, 2010, 16:01 »

Для mapped.
Записан
AlekseyK
Гость
« Ответ #25 : Апрель 16, 2010, 16:39 »

Код
C++ (Qt)
QtConcurrent::mapped(vector, std::bind1st(std::mem_fun(&MyClass::myMethod), this));

Не работает:

Цитировать
c:\Qt\2010.02.1\qt\include/QtCore/../../src/corelib/concurrent/qtconcurrentmapkernel.h:180: error: no match for call to '(std::binder1st<std::mem_fun1_t<QString, MyMainWindow, int&> >) (const int&)'
« Последнее редактирование: Апрель 16, 2010, 17:56 от AlekseyK » Записан
SABROG
Гость
« Ответ #26 : Апрель 16, 2010, 18:04 »

У меня всё работает.

Код
C++ (Qt)
#include <QtConcurrentMap>
#include <functional>
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   QVector<int> test;
   test << 1 << 2 << 3;
 
   QtConcurrent::mapped(test, std::bind1st(std::mem_fun(&MainWindow::myMethod), this));
}
 
int MainWindow::myMethod(int i)
{
   qDebug() << i;
   return i;
}
 

Код:
2 
1
3

Вариант с tr1:

Код
C++ (Qt)
#include <QtConcurrentMap>
#include <tr1/functional>
 
...
QtConcurrent::mapped(test, std::tr1::bind(&MainWindow::myMethod, this, std::tr1::placeholders::_1));
 
« Последнее редактирование: Апрель 16, 2010, 18:45 от SABROG » Записан
AlekseyK
Гость
« Ответ #27 : Апрель 16, 2010, 19:01 »

Спасибо, у меня теперь тоже: заменил указатель на аргумент (как было в примере QtConcurrent) его значением, было так:

Код
C++ (Qt)
int MainWindow::myMethod(int &i)

Собралось. Но теперь myMethod валится на ровном месте. Или такой вызов некорректен, или следующий экземпляр myMethod вызывается до того, как отработал предыдущий и возникает конфликт, такое может быть?
Записан
SABROG
Гость
« Ответ #28 : Апрель 16, 2010, 19:06 »

вызывается до того, как отработал предыдущий и возникает конфликт, такое может быть?

Вообще весь смысл потоков как раз в этом, чтобы методы вызывались и отрабатывались параллельно, без ожидания окончания параллельных потоков. Если у тебя где-то в коде есть подобный конфликт, то нужно переписать, чтобы его не было или пройтись дебагером, чтобы выяснить причину, если одновременного доступа к одному и тому же объекту не предполагается и не наблюдается.
« Последнее редактирование: Апрель 16, 2010, 19:11 от SABROG » Записан
AlekseyK
Гость
« Ответ #29 : Апрель 16, 2010, 19:13 »

вызывается до того, как отработал предыдущий и возникает конфликт, такое может быть?

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

Блин, опять:
Цитировать
The QtConcurrent::map(), QtConcurrent::mapped() and QtConcurrent::mappedReduced() functions run computations in parallel on the items in a sequence such as a QList or a QVector.

Мне нужно, чтобы вычисления выполнялись параллельно потоку главного окна, НО ПОСЛЕДОВАТЕЛЬНО, чтобы оно продолжало реагировать и в него в реальном времени выводился бы лог. Если следующий поток MyMethod запускается до того, как отработал предыдущий, то это не годится т.к. они меняют в цикле один и тот же массив информации последовательно - итерациями, параллельно их выполнять нельзя.
« Последнее редактирование: Апрель 16, 2010, 19:41 от AlekseyK » Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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