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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Консольный проект. Threading.  (Прочитано 4612 раз)
ips
Гость
« : Май 22, 2011, 23:41 »

Привет всем!
Стоит задача: Организовать два потока работующими параллельно. Но почему -то , ни один из потоков не ставит .IsFinished() в true. В Чем беда? Вот исходные файлы

//*******************************************Function.h******************
Код:
#include <QThread>
#include <QTime>

#define ArraySize 30

using namespace std;

unsigned *ArrayPointerI = NULL, *ArrayPointerJ = NULL;
bool *ArrayPointer = NULL;

QTime TimerA;
QTime TimerB;
QTime TimerC;

double FinishA=0;
double FinishB=0;
double FinishC=0;

//Потока А
class FuncA : public QThread{
//Q_OBJECT
public:

void run()
{

TimerA.start();
cout << "Process A Begin\n " << endl;

ArrayPointerI = new unsigned[ArraySize];
ArrayPointerJ = new unsigned[ArraySize];

for(int i = 0 ;i < ArraySize;i++){
cout << "Process A Worked... " << endl;
ArrayPointerI[i] = i;
}

for(int j = 0; j < ArraySize;j++){
cout << "Process A Worked... "<< endl;
ArrayPointerJ[j] = j;
}
FinishA = TimerA.elapsed();
cout <<"Process A is finished Total time (Milisec) : " << FinishA <<"\n"<< endl;

//exec();
}
signals:
void finished();

};

//Потока B
class FuncB : public QThread{
//Q_OBJECT
public:
void run()
{

TimerB.start();
cout << "Process B begin\n" << endl;

ArrayPointer = new bool[ArraySize];

for(int i = 0 ;i < ArraySize;i++){
ArrayPointer[i]=0;
cout << "Process B Worked...\n" << endl;
}

FinishB = TimerB.elapsed();
cout << "Process B Finished Total time (Milisec.) : " << FinishB <<"\n"<< endl;

// exec();
}
signals:
void finished();
};

//Поток C
class FuncC : public QThread{
public:
void run()
{
TimerC.start();

cout << "Process C begin" << endl;

cout << "Process C Worked with data from Process A... " << endl;
delete [] ArrayPointerI;
cout << "Process C Worked with data from Process B..." << endl;
delete [] ArrayPointerJ;

FinishC = TimerC.elapsed();
cout << "Process C Finished.Total time(Millisec.):" << FinishC << endl;

}
};

//**********************************************************end of Function.h**********

//******************* Main.cpp

#include <QtCore/QCoreApplication>
#include <iostream>
#include <QTime>
#include "functions.h"

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

QTime TimeOfApplication;// Таймер всего приложения
TimeOfApplication.start();//Старт таймера всего приложения

FuncA Thread1;
FuncB Thread2;
FuncC Thread3;

//Два процесса, Thread1 && Thread2 выполняем параллельно и не выполняем действия пока они не закочатся

Thread1.start();
Thread2.start();

while( (!Thread1.isFinished() ) && (!Thread2.isFinished())); //Беда isFinished всегда False

/*Весь код дальше начинает выполнятся не смотря даже на условие while*/

if(FinishA > FinishB)
cout << " Process B Finished first\n" <<endl;

else
cout << " Process B Finished first\n" << endl;

cout << "Total time of all Application (Miliseconds): " << TimeOfApplication.elapsed() << endl;
return a.exec();
}
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Май 22, 2011, 23:58 »

Цитировать
while( (!Thread1.isFinished() ) && (!Thread2.isFinished())); //Беда isFinished всегда False
/*Весь код дальше начинает выполнятся не смотря даже на условие while*/
Взаимоисключающие параграфы.
Легко убедиться, что из цикла оно выходит когда один из них закончился:
Код
C++ (Qt)
while( (!Thread1.isFinished() ) && (!Thread2.isFinished()));
cout << Thread1.isFinished() << Thread2.isFinished() <<endl;


Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #2 : Май 23, 2011, 00:25 »

Кроме того ряд замечаний:

1) По циклу while()
Условие, видимо, составлено неправильно. Вы дожидаетесь окончания любого одного потока, но потом сравниваете время выполнения потоков, хотя если один из них к этому времени не завершился, то время выполнения будет равен 0.
Правильное условие
Код
C++ (Qt)
while((!Thread1.isFinished() ) || (!Thread2.isFinished()))
Кроме того не очень хорошо крутить пустой цикл и жрать процессор, намного логично будет отдавать его потокам:
Код
C++ (Qt)
while((!Thread1.isFinished() ) || (!Thread2.isFinished()))
   QThread::yieldCurrentThread();

2) По cout'у:
а) По вашему выводу в консоль видно, что он не потокобезопасен.
Чтобы это встречалось реже надо вместо \n везде использовать endl (который в себя включает flush).
Ну или вместо cout использовать qDebug().
б) надо понимать, что на вывод вы тратите намного больше времени, чем на действия в цикле, так что вы фактически сейчас измеряете время, которое тратится на вывод данных.

3) смысл
Код:
signals:
void finished();
от меня ускользает.
Записан
ips
Гость
« Ответ #3 : Май 23, 2011, 00:33 »

по циклу while
Я же ожидал момента , когда они оба выполнятся !!! Шокированный
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #4 : Май 23, 2011, 00:48 »

Я же ожидал момента , когда они оба выполнятся !!!
Неправильно ждали.

Оба ещё не выполнились:
isFinished = false
!isFinished = true
true && true = true => крутимся в цикле.

Один закончился:
false && true = false => выходим из цикла.
Записан
ips
Гость
« Ответ #5 : Май 23, 2011, 01:00 »

я понимаю , что я туплю . но вопрос
я же хочу выйти из цикла только тогда , когда оба закочатся , а условие false&true не радует!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 23, 2011, 08:11 »

я понимаю , что я туплю . но вопрос
я же хочу выйти из цикла только тогда , когда оба закочатся , а условие false&true не радует!
Не создавайте головоломных if'ов. Потратьте пару строк и запишите условие нормально
Код
C++ (Qt)
while (true) {
if (Thread1.isFinished() && Thread2.isFinished()) break;
QThread::yieldCurrentThread();
}
 
Также не употребляйте "Process" по отношению к Thread (нитка, поток)
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #7 : Май 23, 2011, 08:20 »

я понимаю , что я туплю . но вопрос
Я же у себя в сообщении всё написал уже:
Цитировать
while((!Thread1.isFinished() ) || (!Thread2.isFinished()))
    QThread::yieldCurrentThread();
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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