Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Syveren от Октябрь 03, 2012, 12:01



Название: Приостановить поток [РЕШЕНО]
Отправлено: Syveren от Октябрь 03, 2012, 12:01
Подскажите, знающие люди, правильно ли так приостанавливать дополнительный поток(всего 1) из главного.
Код работает, поток приостанавливается, но чую здесь какой-то подвох. :-\
Приоставливаю/бужу поток методом myThread->wake()/myThread->pause() вызванным из главного потока.
Код
C++ (Qt)
class MyThread : public QThread
{
public:
...
   void wake()  {  pauseMutex.unlock();}
   void pause() {  pauseMutex.lock();}
private:
  QMutex pauseMutex;
  void run()
  {    
        int i = 0;
        while(1)
        {
             pauseMutex.lock();
             pauseMutex.unlock();
             qDebug()<<"vipolnenie "<<i++;
             sleep(1);
        }
  }
 
};


Название: Re: Приостановить поток
Отправлено: Igors от Октябрь 03, 2012, 12:12
Проще и лучше использовать QSemaphore который для этого и предназначен. А так Вы не можете безболезненно вызвать pause - а вдруг она уже была вызвана?

Ну и подразумевается что "квант задачи" (тело while) достаточно мал, напр сама печать не остановится


Название: Re: Приостановить поток
Отправлено: Syveren от Октябрь 03, 2012, 12:21
Цитировать
напр сама печать не остановится
Но ведь 2рой поток не сможет залокнуть mutex и будет вынужден ждать, и выполнения дальнейшего кода не будет?
В моем случае сообщения после mutex.lock(); mutex.unlock() не выводяться (правда и код другой), но всё же.
QSemaphore это же что-то вроде QMutex-а, только с счётчиком блокировок?


Название: Re: Приостановить поток
Отправлено: Igors от Октябрь 03, 2012, 12:37
Цитировать
напр сама печать не остановится
Но ведь 2рой поток не сможет залокнуть mutex и будет вынужден ждать, и выполнения дальнейшего кода не будет?
Да, но выполнится весь код до lock (qDebug, sleep), в любом случае останов "не мгновенный"

QSemaphore это же что-то вроде QMutex-а, только с счётчиком блокировок?
Да


Название: Re: Приостановить поток
Отправлено: Syveren от Октябрь 03, 2012, 14:29
Цитировать
в любом случае останов "не мгновенный"
мгновенная остановка и не нужна.
Цитировать
Проще и лучше использовать QSemaphore который для этого и предназначен.
А QWaitCondition может быть использован для этой задачи? Думал в начале ипользовать его вместе с мьютексом, но побыстрому сделать не вышло, поток засыпал намертво. Пытаясь разобраться, убрал QWaitCondition, оставил мьютекс. В итоге всё работает.
Сделал так.
Код
C++ (Qt)
...
 
    volatile bool is_waiting;
    void wake()
   {
       if(!is_waiting)
             return;
       pause_mutex.unlock();
       is_waiting = false;
   }
   void pause()
   {
       if(is_waiting)
           return;
       bool locked = pause_mutex.tryLock();
       Q_ASSERT(locked);
       is_waiting = true;
   }
 
  void run()
  {
       is_waiting=false;
       ...
       if(is_waiting)
       {
            pauseMutex.lock();
            pauseMutex.unlock();
       }
       ...
  }
...


Название: Re: Приостановить поток
Отправлено: Igors от Октябрь 03, 2012, 16:46
Накрутили бог знает что. Трудно что ли прочитать простенький класс и воспользоваться?
Код
C++ (Qt)
...
    void wake()
   {
       is_waiting = false;
       mSemaphore.release();
   }
 
   void pause()
   {
       is_waiting = true;
   }
 
  void run()
  {
       is_waiting=false;
       ...
       while (true) {
        if (is_waiting)
         mSemaphore.acquire();
        ...
       }
  }