PDA

View Full Version : Problem with QtConcurrent::run



januszmk
28th July 2011, 21:30
Hello.
I want to have variable number of threads in my application depends of settings.
I am using QtConcurrent::run because then I can run any function of any class.
I did something like this:

QVector<QFuture<void> > asda;
for(i=0; i<n; i++)
{
asda[i] = QtConcurrent::run(this, &MainWindow::thr1);
}
for(i=0; i<n; i++)
{
asda[i].waitForFinished();
}
but when it is runing MainWindow::thr1 for the second time, then I get aplication error and:

app.exe exited with code -1073741819
my header file:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <mailbox.h>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QtCore>
#include <QFileDialog>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_pushButton_clicked();
void upd(int numer, int percent, int speed);

void on_pushButton_3_clicked();

void on_pushButton_2_clicked();

private:
QStandardItem *item;
QStandardItemModel *model;
Ui::MainWindow *ui;
std::string generate();
mailbox *mailb[8];
void thr1();
QString dir;
void download();
};

#endif // MAINWINDOW_H

and MainWindow::thr1 function is just for testing:

void MainWindow::thr1()
{
qDebug() << "test";
}
What am I doing wrong?
I would be grateful, if someone could help.
Janusz

nosleduc
29th July 2011, 00:49
The asda vector is not correctly initialized, you have to set the size before using the operator[]

januszmk
29th July 2011, 08:40
thanks, I replace = with pushback and it is working now. But I have one more question, how can I close the threads when my application is closing, if i don't wait for finished? Because when I am closing application, just window is closing.

nosleduc
29th July 2011, 15:37
One possible solution is to add a flag in your class to see if the user wants to quit the application and deals with it directly in your function thr1 to abort the computation.

januszmk
29th July 2011, 16:14
thanks for help

januszmk
30th July 2011, 17:57
I get one more problem with QtConcurrent::run, When I run this function:

void MainWindow::download()
{
QItemSelection selection( ui->tableView->selectionModel()->selection() );
foreach( const QModelIndex & index, selection.indexes() )
{
rows.append( index.row() );
}
down1 = rows.count();
if(ui->lineEdit_3->text().isEmpty())
{
on_pushButton_3_clicked();
}
watek.clear();
for(down=0; down<8; down++)
{
connect(mailb[down], SIGNAL(progress(int,int,int)), this, SLOT(upd(int,int,int)));
connect(mailb[down], SIGNAL(done(int)), this, SLOT(asda(int)));
QString temp1 = ui->tableView->model()->data(ui->tableView->model()->index(rows[down],0)).toString();
QString temp2 = ui->tableView->model()->data(ui->tableView->model()->index(rows[down],1)).toString();
mailb[down]->number = rows[down];
mailb[down]->number1 = down;
QString type = mailb[down]->type.c_str();
temp1 = ui->lineEdit_3->text() + "/" + temp1;
qDebug() << temp1 << temp2;
watek.push_back(QtConcurrent::run(mailb[down], &mailbox::downloadFile, temp2, temp1));
//mailb[0]->downloadFile(temp2, temp1);
}
}
function downloadFile is run just twice, not 8 times. Is there maybe some limits for number of threads? If there are, then how can I bypass that limits?

Edit:
I found then QtConcurrent is using QThreadPool and I add "QThreadPool::globalInstance()->setMaxThreadCount(10);" and now it's working