crossplatform.ru

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

> [РЕШЕНО] Работа таймеров в параллельном потоке
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();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Litkevich Yuriy
  опции профиля:
сообщение 30.11.2009, 16:25
Сообщение #2


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

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

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




Репутация:   94  


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


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

Группа: Участник
Сообщений: 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:46
Сообщение #4


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

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

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




Репутация:   44  


Попробуй такой код:
void ContinueRotation::run()
{
    QTimer timerReading;
    connect(&timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    timerReading.start(1000);
    exec();
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 18:01
Сообщение #5


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

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

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




Репутация:   17  


Не попадает....

Так.... попало. Интересно, а такой код приемлем?
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
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);
    exec();

    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;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.11.2009, 18:05
Сообщение #6


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

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

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




Репутация:   44  


Цитата(AD @ 30.11.2009, 17:57) *
Не попадает....

В консоль что нибудь пишет?

добавь отладочный вывод:
void ContinueRotation::run()
{
    QTimer timerReading;
    qDebug() << connect(&timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    
    qDebug() << "Start timer"
    timerReading.start(1000);

    qDebug() << "Start eventloop"
    exec();
    qDebug() << "Stop eventloop"
}

Проверь, запускается ли нитка и т.д.


Цитата(AD @ 30.11.2009, 18:01) *
Так.... попало. Интересно, а такой код приемлем?

Нет.
Твой цикла будет запущен после выхода из метода exec и таймер уже сигналы отправлять не будет.

Ты должен выбрать, или использовать таймер с сигналами и запускать exec, или запускать свой цикл и не использовать таймер.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 18:07
Сообщение #7


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

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

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




Репутация:   17  


Ну... я уже ведь сказал, что запускается.... Проблема уже немного в другом: подружить мой цикл и вызов этого таймера... А вот как это сделать?
qDebug() выдает ошибку:
Цитата
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDebug' (or there is no acceptable conversion)

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 30.11.2009, 18:18
Сообщение #8


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

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

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




Репутация:   17  


Мда... Грустно, что нельзя это сделать. Задачка в следующем, которую никак не могу решить:
В этом потоке я отправляю на COM-порт команды, которые принимает прожектор. Ну команды расшифровываются так: повернуть на столько-то вверх, на столько-то вправо, на столько-то вниз, на столько-то влево. Одновременно мне нужно принимать от прожектора команды и анализировать. Ну что оно уже повернул на столько-то.

В своем цикле у меня делается следующее:
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;
    }

Имеется счетчик времени. При определенном значении этого счетчика (раз в минуту) запускается функция выдачи команд, которая и занимается отправкой команд:
writing functions
/// Слот работы прожектора - вращения в обеих плоскостях
void ContinueRotation::workSpotlight()
{
    timerTicks();
    geted_angle_elev = -1, geted_azimuth = -1;

    /// Перемещение вниз и вправо до упора
    _angle_elevation = -110 * 10, _azimuth = 170 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    _is_time_read = true;
/// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ.
    timerTicks();

    /// Перемещение вверх и влево до упора
    _angle_elevation = 10 * 10;        _azimuth = -170 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    _is_time_read = true;
/// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ.
    timerTicks();

    /// Возврат в исходное положение
    _angle_elevation = 0;        _azimuth = 0;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    timerTicks();
}

Как видно из комментариев есть пара мест, где необходимо проверить значения, что я и пытался реализовать с помощью таймера.

Функции чтения выглядят так:
reading functions
/// Получение азимута
void ContinueRotation::readAzimuth(int& geted_azimuth, double limit)
{
    if(!imitTsl) return;
    QTime begining_time(QTime::currentTime());
    while(geted_azimuth < ((limit - 1.5) * 10) || geted_azimuth > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_azimuth = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim);
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 45) break;
        msleep(10);
    }
}

/// Получение угла места
void ContinueRotation::readAngleElevation(int& geted_angle_elev, double limit)
{
    if(!imitTsl) return;
    QTime begining_time(QTime::currentTime());
    while(geted_angle_elev < ((limit - 1.5) * 10) || geted_angle_elev > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_angle_elev = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev);
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 45) break;
        msleep(10);
    }
}

/// Слот чтения из COM-порта
void ContinueRotation::reading()
{
    if(!_is_time_read) return;

    readAngleElevation(geted_angle_elev, (double)_angle_elevation / 10.);
    readAzimuth(geted_azimuth, (double)_azimuth / 10.);
    _is_time_read = false;
}


Если у кого-то возникнут идеи, как это сделать, буду благодарен. Пока никаких других идей не возникает.... :(

Сообщение отредактировал AD - 30.11.2009, 18:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- AD   [РЕШЕНО] Работа таймеров в параллельном потоке   30.11.2009, 12:48
- - BRE   1. Обрати внимание, таймер создается в главном пот...   30.11.2009, 12:51
|- - AD   Цитата(BRE @ 30.11.2009, 12:51) 1. Обрати...   30.11.2009, 15:31
- - Litkevich Yuriy   AD, таймер так и остался в главном потоке. Помести...   30.11.2009, 15:45
|- - AD   Цитата(Litkevich Yuriy @ 30.11.2009, 15:4...   30.11.2009, 15:49
|- - BRE   Цитата(AD @ 30.11.2009, 15:49) Почему в г...   30.11.2009, 16:11
- - Litkevich Yuriy   BRE, понял, ведь это следует из задачи   30.11.2009, 16:25
|- - AD   Мда... Руки у меня, что-ли, кривые.... Не выходит....   30.11.2009, 17:02
|- - BRE   Проверка и испускание сигнала от таймера происходи...   30.11.2009, 17:24
||- - AD   Цитата(BRE @ 30.11.2009, 17:24) Проверка ...   30.11.2009, 17:27
||- - BRE   Цитата(AD @ 30.11.2009, 17:27) А я правил...   30.11.2009, 17:29
||- - AD   Блин. Я убрал строку остановки таймера, но в слот ...   30.11.2009, 17:38
|- - BRE   Попробуй такой код: void ContinueRotation:...   30.11.2009, 17:46
|- - AD   Не попадает.... Так.... попало. Интересно, а тако...   30.11.2009, 18:01
|- - BRE   Цитата(AD @ 30.11.2009, 17:57) Не попадае...   30.11.2009, 18:05
|- - AD   Ну... я уже ведь сказал, что запускается.... Пробл...   30.11.2009, 18:07
|- - BRE   Цитата(AD @ 30.11.2009, 18:07) Ну... я уж...   30.11.2009, 18:09
|- - AD   Мда... Грустно, что нельзя это сделать. Задачка в ...   30.11.2009, 18:18
|- - BRE   Что делает этот код? for(int timer_count=0; QT...   30.11.2009, 18:29
- - Litkevich Yuriy   Цитата(AD @ 30.11.2009, 20:27) А я правил...   30.11.2009, 18:02
- - BRE   Или делать такой изврат: void ContinueRotation...   30.11.2009, 18:19
- - Litkevich Yuriy   AD, ты уже в который раз спускаешся до подробносте...   30.11.2009, 18:23
|- - AD   Цитата(Litkevich Yuriy @ 30.11.2009, 18:2...   30.11.2009, 18:24
- - Litkevich Yuriy   Цитата(AD @ 30.11.2009, 21:24) Идея, а не...   30.11.2009, 18:29
- - AD   Цитата(Litkevich Yuriy @ 30.11.2009, 18:2...   30.11.2009, 18:38
- - BRE   Цитата(AD @ 30.11.2009, 18:38) Надо как-т...   30.11.2009, 18:43


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


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




RSS Текстовая версия Сейчас: 16.1.2025, 3:16