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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Многопоточное вычисление функции  (Прочитано 10650 раз)
qtest
Гость
« : Июнь 17, 2013, 23:08 »

Здравствуйте.
Есть работающий код, нормально выводящий результаты каждого потока по отдельности, как синхронизовать их для вывода в одну переменную в мейне? Пытался читать про мьютексы и семафоры - ничего понятного не нашел.
Наиболее простой пример:
Код:
#include <QCoreApplication>
#include <QThread>


class thread : public QThread
{
public:
    int st,end,a,ans;
    int f(){
        int answ=0;
        for(int i=st;i<end;i++)
            answ+=a;
        return answ;
    }
    void run(){
        ans=f();
    }

};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    int a,n,m,i;
    scanf("%i %i %i",&a,&n,&m);
    int *d=new int[m];
    thread *t=new thread[m];

    for(i=0;i<m;i++){
        d[i]=(i+1)*n/m;
        if(i==0){
            t[i].st=0;
            t[i].end=d[i];
        }
        else if(i==(m-1)){
            t[i].st=d[i-1];
            t[i].end=n;
        }
        else{
            t[i].st=d[i-1];
            t[i].end=d[i];
        }
        t[i].a=a;

    }

    printf("\nstarted\n\n");

    for(i=0;i<m;i++)
        t[i].start(QThread::HighPriority);
   
    return app.exec();
}
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Июнь 18, 2013, 00:19 »

Во-первыйх, юзайте QtConcurrent. Во-вторых... ну, вобщем, разберетесь.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июнь 18, 2013, 13:02 »

Здравствуйте.
Есть работающий код, нормально выводящий результаты каждого потока по отдельности, как синхронизовать их для вывода в одну переменную в мейне?
Может имелось ввиду "как накапливать сумму в main"? Если у Вас нитки запускаются один раз, то можно и без синхронизации
Код
C++ (Qt)
// ждем пока все нитки отработают
for(i = 0; i < m; i++)
  t[i].wait();
 
// суммирует результаты
int sum = 0;
for(i = 0; i < m; i++)
  sum += t[i].ans;
 
Записан
qtest
Гость
« Ответ #3 : Июнь 19, 2013, 11:11 »

Во-первыйх, юзайте QtConcurrent. Во-вторых... ну, вобщем, разберетесь.
Судя по описанию, он автоматически распараллеливает задачу на имеющееся количество ядер, это конечно даже эффективнее, но возможно ли самому указать количество потоков?
Может имелось ввиду "как накапливать сумму в main"? Если у Вас нитки запускаются один раз, то можно и без синхронизации
А если то же самое, но с накоплением суммы в глобальную переменную в самой f() и ее выводом в мейне? Т.е. цель - не столько решение конкретной задачи, сколько понимание мьютексов и семафоров.
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #4 : Июнь 19, 2013, 11:28 »

, но возможно ли самому указать количество потоков?
http://qt-project.org/doc/qt-5.0/qtcore/qthreadpool.html#globalInstance
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июнь 19, 2013, 11:49 »

А если то же самое, но с накоплением суммы в глобальную переменную в самой f() и ее выводом в мейне? Т.е. цель - не столько решение конкретной задачи, сколько понимание мьютексов и семафоров.
Ну если "не выжимать скорость" то все очень просто
Код:
void run(){
    ans=f();
    QMutextLocker locker(&mutex);   // mutex должен быть напр глобальной переменной, т.е. один и тот же для всех ниток
    sum += ans;
}
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #6 : Июнь 19, 2013, 12:35 »

Я бы курил в сторону std::future + std::async
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #7 : Июнь 19, 2013, 13:48 »

Я бы курил в сторону std::future + std::async

Тот же конкурент, только убогий.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 19, 2013, 13:55 »

Тоже мне "курцы"
Код
C++ (Qt)
#pragma omp parallel for reduction(+: sum)
for (int i = 0; i < limit; ++i)
sum += DoCalc(i);
 
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Июнь 19, 2013, 14:22 »

Тоже мне "курцы"
Фи. По начитались букварей по OpenMP...
Где взрослый суровый велосипед? Подмигивающий
Записан
qtest
Гость
« Ответ #10 : Июнь 19, 2013, 15:48 »

Код:
#include <QCoreApplication>
#include <QThread>
#include <QMutex>

QMutex mutex;

int answer=0;

class thread : public QThread
{
public:
    int st,end,a,ans;
    int f(){
        int answ=0;
        for(int i=st;i<end;i++)
            answ+=a;
        return answ;
    }
    void run(){

        ans=f();
       // printf("\nst = %i, end = %i, result = %i",st,end,ans);
        mutex.lock();
        answer+=ans;
        mutex.unlock();
    }

};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    int a,n,m,i;
    scanf("%i %i %i",&a,&n,&m);
    int *d=new int[m];
    thread *t=new thread[m];

    for(i=0;i<m;i++){
        d[i]=(i+1)*n/m;
        if(i==0){
            t[i].st=0;
            t[i].end=d[i];
        }
        else if(i==(m-1)){
            t[i].st=d[i-1];
            t[i].end=n;
        }
        else{
            t[i].st=d[i-1];
            t[i].end=d[i];
        }
        t[i].a=a;

    }

    printf("\nstarted\n\n");

    for(i=0;i<m;i++)
        t[i].start(QThread::HighPriority);

    for(i=0;i<m;i++)
        t[i].wait();
    printf("\nAnswer = %i\n",answer);


    return app.exec();
}
Это правильно? Как можно сделать то же самое, но с помощью семафора, а не wait()?

Код:
QMutextLocker locker(&mutex);
answer+=ans;
Не работает, он делает то же самое?
Код:
  mutex.lock();
        answer+=ans;
        mutex.unlock();
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Июнь 19, 2013, 15:51 »

Не работает...
Что значит не работает?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Июнь 19, 2013, 16:52 »

Это правильно? Как можно сделать то же самое, но с помощью семафора, а не wait()?
QThread::wait - просто ждем когда нитка отработает, к мутексу это отношения не имеет

Не работает, он делает то же самое?
Да, то же самое и работать должно

Хотите потренироваться - возьмите задачу. Напр на семафоры:

- одна нитка читает символ (напр с клавы), другая нитка этот символ печатает

Фи. По начитались букварей по OpenMP...
Где взрослый суровый велосипед? Подмигивающий
Был, и даже вполне успешно боролся с реализацией gcc 4.4. Но против интеловской не устоял   Улыбающийся
Записан
qtest
Гость
« Ответ #13 : Июнь 19, 2013, 18:18 »

Хотите потренироваться - возьмите задачу. Напр на семафоры:

- одна нитка читает символ (напр с клавы), другая нитка этот символ печатает
Код:
#include <QCoreApplication>
#include <QThread>
#include <QMutex>
QMutex mutex;
char c;

class rthread : public QThread
{
    void run(){
        for(;;){
        mutex.lock();
        c=getchar();
        mutex.unlock();
        }
    }
};

class wthread : public QThread
{
    void run(){
        for(;;){
        mutex.lock();
        putchar(c);
        mutex.unlock();
        }
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    rthread r;
    wthread w;
    r.start(QThread::HighPriority);
    w.start(QThread::HighPriority);
    printf("\nStarted\n\n");
    return a.exec();
}
Так?
Что значит не работает?
Код:
Mutext
Все работает, только не совсем понятно что и как он делает.


Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Июнь 19, 2013, 19:16 »

Все работает, только не совсем понятно что и как он делает.
Оно делает тоже что и ваш код, только безопасно. Эта конструкция никогда не забудет освободить ресурс, что нельзя сказать о человеке. Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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