Russian Qt Forum

Qt => Общие вопросы => Тема начата: 0xFF от Март 24, 2010, 21:45



Название: QThread, ожидание в потоке
Отправлено: 0xFF от Март 24, 2010, 21:45
Доброго времени суток
Функция run() выглядит примерно так

Код
C++ (Qt)
void myThread::run() {
for(int i=0; i<dataSize; ++i) {
obj->func(i);
...
stopped = false;
while( !stopped ) {}
}
}

Собственно нужно подождать пока выполнится obj->func(i),  для этого использую while( !stopped ) {}, переменная stopped меняется при поступлении сигнала от obj.
Но что-то этот while( !stopped ) {} кажется каким-то "говнистым", есть другие способы?


Название: Re: QThread, ожидание в потоке
Отправлено: SimpleSunny от Март 24, 2010, 22:13
Можно добавить слот, в который будет приходить сигнал.

Код:
f1()
{
if (i >= dataSize())
quit;

obj->func(i);
}

f2()
{
++i;
f1();
}

run()
{
i = 0;
f1();
exec();
}


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 24, 2010, 23:49
Код:
void myThread::run() {
for(int i=0; i<dataSize; ++i) {
obj->func(i);
...
QMutex m;
                m.lock();

                waitCondition.wait( &m );
}
}
waitCondition - это QWaitCondition. А там где ты меняешь stopped, сделай waitCondition.wakeOne();


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 24, 2010, 23:53
Код
C++ (Qt)
stopped = false;
while( !stopped ) {}
 
Так плохо! Процессор конкретно грузим!


Название: Re: QThread, ожидание в потоке
Отправлено: 0xFF от Март 25, 2010, 01:04
Хм, спасибо за ответы.


Название: Re: QThread, ожидание в потоке
Отправлено: Igors от Март 25, 2010, 11:48
Код
C++ (Qt)
void myThread::run() {
for(int i=0; i<dataSize; ++i) {
obj->func(i);
...                       // что если stopped = true будет в этот момент?
stopped = false;    // или в этот?
while( !stopped ) {}  //  а не в этот как рассчитывали
}
}
QMutex здесь не подходит, если нитка захватила мутекс - она же (и только она) должна его освободить. Цивильное решение - использовать семафор

Код
C++ (Qt)
QSemaphore theSemaphore;
...
void myThread::run() {
for(int i=0; i<dataSize; ++i) {
               theSemaphore.acquire();
obj->func(i);
}
}
А "наблюдающий" должен открыть семафор
Код:
theSemaphore.release();


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 25, 2010, 12:00
Код
C++ (Qt)
void myThread::run() {
for(int i=0; i<dataSize; ++i) {
obj->func(i);
...                       // что если stopped = true будет в этот момент?
stopped = false;    // или в этот?
while( !stopped ) {}  //  а не в этот как рассчитывали
}
}
QMutex здесь не подходит, если нитка захватила мутекс - она же (и только она) должна его освободить. Цивильное решение - использовать семафор
Цитировать
void myThread::run() {
       QMutex m;
   for(int i=0; i<dataSize; ++i) {
      obj->func(i);
      ...
                m.lock();
                waitCondition.wait( &m );
                m.unlock();
   }
}
А там где ты меняешь stopped, сделай waitCondition.wakeOne();


Название: Re: QThread, ожидание в потоке
Отправлено: Igors от Март 25, 2010, 12:51
Через waitCondition тоже можно, но тогда по-моему так
Код
C++ (Qt)
void myThread::run() {
      QMutex m;
for(int i=0; i<dataSize; ++i) {
               m.lock();
obj->func(i);
...
               waitCondition.wait( &m );
               m.unlock();
}
}
 


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 25, 2010, 13:28
Смысл? wakeOne может вызваться только после obj->func(i) (это конечно, если я код правильно понимаю ;)).


Название: Re: QThread, ожидание в потоке
Отправлено: Igors от Март 25, 2010, 14:32
Смысл? wakeOne может вызваться только после obj->func(i) (это конечно, если я код правильно понимаю ;)).
wakeOne вызывается из др. нитки, поэтому если оно придет до того как мутекс заперт - будет не гуд


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 25, 2010, 15:21
Смысл? wakeOne может вызваться только после obj->func(i) (это конечно, если я код правильно понимаю ;)).
wakeOne вызывается из др. нитки, поэтому если оно придет до того как мутекс заперт - будет не гуд
Точняк :)


Название: Re: QThread, ожидание в потоке
Отправлено: Igors от Март 25, 2010, 16:34
Нет, не выплясывается через wakeOne - этот метод не имеет эффекта если нет "ожидающих". Значит если wakeOne проскочит до wait - тому остается ждать forever  :'(

Мда... а на примерах все так легко и понятно  :)


Название: Re: QThread, ожидание в потоке
Отправлено: SASA от Март 25, 2010, 17:04
Код:
bool stopped;
QMutex stoppedMutex;

void setStopped(bool _s)
{
stoppedMutex.lock();
stopped = _s;
stoppedMutex.unLock();
}
bool sStopped()
{
stoppedMutex.lock();
return stopped;
stoppedMutex.unLock();

}
void run()
{
...
while( !isStopped() ) { sleep(1); }  //  а не в этот как рассчитывали
...
}
Работает, процессор не грузит.
Но если семафор позволяет работать из разных потоков, он будет быстрее.


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 25, 2010, 17:30
Код:
bool stopped;
QMutex stoppedMutex;

void setStopped(bool _s)
{
stoppedMutex.lock();
stopped = _s;
stoppedMutex.unLock();
}
bool sStopped()
{
stoppedMutex.lock();
return stopped;
stoppedMutex.unLock();

}
void run()
{
...
while( !isStopped() ) { sleep(1); }  //  а не в этот как рассчитывали
...
}
Работает, процессор не грузит.
Но если семафор позволяет работать из разных потоков, он будет быстрее.
Под виндой не скомпилится!


Название: Re: QThread, ожидание в потоке
Отправлено: pastor от Март 25, 2010, 19:10
Код
C++ (Qt)
bool sStopped()
{
stoppedMutex.lock();
return stopped;
stoppedMutex.unLock();
 
}

unLock после return это сильно.


Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 25, 2010, 19:28
Код
C++ (Qt)
bool sStopped()
{
stoppedMutex.lock();
return stopped;
stoppedMutex.unLock();
 
}

unLock после return это сильно.
Код
C++ (Qt)
bool sStopped()
{
       QMutexLocker lock( &stoppedMutex );
return stopped;
}


Название: Re: QThread, ожидание в потоке
Отправлено: SASA от Март 26, 2010, 00:14
unLock после return это сильно.
Код
C++ (Qt)
bool isStopped()
{
       QMutexLocker lock( &stoppedMutex );
return stopped;
}
[/quote]
Спасибо за замечание. Я сам пользуюсь QMutexLocker, поэтому на ретуны внимания не обращаю.
Цитировать
Под виндой не скомпилится!
Почему?



Название: Re: QThread, ожидание в потоке
Отправлено: alexman от Март 26, 2010, 13:44
unLock после return это сильно.
Код
C++ (Qt)
bool isStopped()
{
       QMutexLocker lock( &stoppedMutex );
return stopped;
}
Спасибо за замечание. Я сам пользуюсь QMutexLocker, поэтому на ретуны внимания не обращаю.
Цитировать
Под виндой не скомпилится!
Почему?
[/quote]
sleep


Название: Re: QThread, ожидание в потоке
Отправлено: Akaiten от Март 26, 2010, 17:26
sleep
Странно, есть же QThread::sleep() или что тоже самое под виндой - WinAPI функция Sleep().


Название: Re: QThread, ожидание в потоке
Отправлено: Igors от Март 27, 2010, 12:45
Предлагаю так через wakeOne
Код
C++ (Qt)
void myThread::run() {
QMutex m;
m.lock();
for(int i = 0; i <= dataSize; ++i) {
 if (i) waitCondition.wait(&m);
 if (i < dataSize) obj->func(i);
}
m.unlock();
}