crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V   1 2 3 >  
Ответить в данную темуНачать новую тему
> [РЕШЕНО] Работа таймеров в параллельном потоке
AD
  опции профиля:
сообщение 30.11.2009, 12:48
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


По каким-то причинам не работает таймер, который я хочу запустить в параллельном потоке.
В чем могут быть проблемы?
/// Класс потока - вращение вокруг осей заданное количество времени - длительное вращение
class ContinueRotation: public QThread
{
    Q_OBJECT

private:
     QTimer _timerReading;            ///< таймер для запуска чтения из COM-порта

public:
     void startTimerReading() { _timerReading.start(1000); }
};


/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
    connect(&_timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    ///
}

/// Запуск работы прожектора - ГЛАВНЫЙ поток
void ContinuousWork::startControl()
{
///
  _continue -> startTimerReading();
    _continue -> start();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.11.2009, 12:51
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


1. Обрати внимание, таймер создается в главном потоке!
2. В run() добавь exec().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 15:31
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(BRE @ 30.11.2009, 12:51) *
1. Обрати внимание, таймер создается в главном потоке!
2. В run() добавь exec().

Изменил. Не помогло. <_<

Code:
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
    connect(&_timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    _timerReading.start(1000);
///................
        exec();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 30.11.2009, 15:45
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


AD, таймер так и остался в главном потоке.
Помести его в run().


П.С. А собственно будет ли влиять положение таймера, ведь ему не устанавливается родительский объект?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 15:49
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 30.11.2009, 15:45) *
AD, таймер так и остался в главном потоке.
Помести его в run().

Почему в главном? Не понимаю:
/// Класс потока - вращение вокруг осей заданное количество времени - длительное вращение
class ContinueRotation: public QThread
{
    Q_OBJECT

private:
    QTimer _timerReading;                        ///< таймер для запуска чтения из COM-порта

private slots:
    void reading();
};

/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
/// ................
    connect(&_timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    _timerReading.start(1000);

///      for(int timer_count=0; QTime::currentTime()<=finished_time;) { .... }

/// ..........

    exec();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.11.2009, 16:11
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(AD @ 30.11.2009, 15:49) *
Почему в главном? Не понимаю:

Потому что вызов конструктора объекта ContinueRotation выполняется в контексте главной нити (точнее той из которой он конструируется), а свой контекст нить получает, только при входе в метод run(). Либо перенеси создание таймера в run или попробуй делать ему moveToThread.

Цитата(Litkevich Yuriy @ 30.11.2009, 15:45) *
П.С. А собственно будет ли влиять положение таймера, ведь ему не устанавливается родительский объект?

Будет влиять на то, где будет крутиться таймер, точнее в чьем цикле обработки событий он будет проверяться и откуда будет испускаться сигнал.


Сообщение отредактировал BRE - 30.11.2009, 16:05
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 30.11.2009, 16:25
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


BRE, понял, ведь это следует из задачи :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 17:02
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Мда... Руки у меня, что-ли, кривые.... Не выходит.... :huh:
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
    connect(imitTsl, SIGNAL(continue_stop()), SLOT(exit()));
    connect(this, SIGNAL(working_light()), SLOT(workSpotlight()));

    QTimer timerReading;
    connect(&timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    timerReading.start(1000);

    for(int timer_count=0; QTime::currentTime()<=finished_time;)
    {
        if(_finished) break;
        timerTicks();
        if(timer_count == 60) timer_count = 0;
        if(!timer_count) emit working_light();
        ++timer_count;
    }

    emit work_ending();
    _is_time_read = false;
    timerReading.stop();
    exec();
}

Вот полная версия run(). Все-равно, не попадает в reading().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.11.2009, 17:24
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Проверка и испускание сигнала от таймера происходит в цикле обработки событий, который запускается методом exec.
А у тебя к этому времени таймер уже остановлен.


Сообщение отредактировал BRE - 30.11.2009, 17:24
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 17:27
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(BRE @ 30.11.2009, 17:24) *
Проверка и испускание сигнала от таймера происходит в цикле обработки событий, который запускается методом exec.
А у тебя к этому времени таймер уже остановлен.

Хорошо, спасибо. А я правильно понимаю, что это таймер заканчивает свое действие, как только программа выходит из функции run()?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V   1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 23.1.2022, 21:59