Parallel Programming Qt C ++

1

I'm starting to learn parallel programming, and I'm wanting to compare a single threaded program to a multithreaded one.

What I thought was to make a very simple algorithm that, within a period of 1 minute, calculate the largest number of possible prime numbers, and show me the last calculated prime number and its position in the prime numbers, for example , let's say it was number 23, would appear the number 23 and its position, in case 9, since it is the 9th prime number.

I used QtConcurrent to split the threads.

Without using parallelism, the number found was 117779, at position 119963. However, when using parallelism, I got the number 198227, at position 17934 (wrong position and wrong number, this value is not prime and the previous cousin had position 17839, much smaller than the position shown at the end). I think I have to use the library, but I can not find a way to implement it in my code.

Below is the code:

#include <QCoreApplication>
#include <qtconcurrentrun.h>
#include <QFutureSynchronizer>
#include <QThread>
#include <time.h>
#include <iostream>
using namespace std;

time_t endwait;

int ehPrimo(int num) {
    int  i;
    for (i=2; i<=num/2; i++)
        if (num%i==0) return 0;
    return 1;
}

void funcThread(QString name, int *p, int *n, int *u){
    while (time (NULL) < endwait){
        if(ehPrimo(*p)) {
            *n = *n + 1;
            *u = *p;
        }
        *p = *p + 2;
        //qDebug() << endl << name << " p"<<*p<<" n"<<*n<<" u"<<*u << "from: " << QThread::currentThread();
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    int p = 5, n = 2, u=p;
    int seconds = 5;

    endwait = time (NULL) + seconds;

    QFuture<void> t1 = QtConcurrent::run(funcThread, QString("A"), &p,&n,&u);
    QFuture<void> t2 = QtConcurrent::run(funcThread, QString("B"), &p,&n,&u);
    QFuture<void> t3 = QtConcurrent::run(funcThread, QString("C"), &p,&n,&u);
    QFuture<void> t4 = QtConcurrent::run(funcThread, QString("D"), &p,&n,&u);


    t1.waitForFinished();
    t2.waitForFinished();
    t3.waitForFinished();
    t4.waitForFinished();

    cout << "\n\n Encontrou " << n << " primos.";
    cout << "\n\n Ultimo primo: " << u << ".\n\n";



    return a.exec();
}
    
asked by anonymous 04.05.2017 / 07:41

1 answer

1

As far as I understand, your code tries to do the calculation in a certain time interval, so I think it's normal for the position to vary. On the wrong result (the number is not prime), I believe this happens because your threads are using their variables in a wrong order because their function is out of sync. This is called race condition .

When you "fire" a new thread, you have no control over it. You need to use some feature to prevent it from doing unexpected things like modifying a variable to another thread or in a different order than you expect.

I used QMutex to lock your function and the result here was always a prime number.

time_t endwait;
QMutex mutex;

int ehPrimo(int num) {
    for (int i=2; i<=num/2; i++)
        if (num%i==0) return 0;
    return 1;
}

void funcThread(QString name, int *p, int *n, int *u) {
    QMutexLocker lock(&mutex);
    while (time (NULL) < endwait){
        if(ehPrimo(*p)) {
            *n = *n + 1;
            *u = *p;
        }
        *p = *p + 2;
    }
}

Search for thread synchronization and class QMutex, QWaitCondition, etc. link

    
04.05.2017 / 13:08