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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Таймер в потоке  (Прочитано 11229 раз)
Andrew Vladoff
Гость
« : Февраль 20, 2011, 20:51 »

В потоке обрабатываются определенные данные. Одной функцией потока данные добавляются в список, а по таймеру этот список очищается. Нужно ли использовать критические секции во время срабатывания таймера? Таймер запускается в этом же потоке или для него создается отдельный?
Записан
BRE
Гость
« Ответ #1 : Февраль 20, 2011, 20:59 »

Ты бы показал, как у тебя это все происходит.
Если я правильно тебя понял, то можно сделать так, что бы синхронизацией занималась сама очередь сообщений потока.
Записан
Andrew Vladoff
Гость
« Ответ #2 : Февраль 21, 2011, 08:52 »

Цитировать
Ты бы показал, как у тебя это все происходит.
Если в двух словах.
Есть поток

Код:
//---------------------------------------------------------------------------
void CThr::run(void)
{
  // Объявляем Таймер
   pTimer = new QTimer(this);
   connect(pTimer, SIGNAL(timeout()), this, SLOT(s_OnTimer()));
   pTimer->start(1000);

   //--------- чтение пакетов и заполнение списка
  while (!flStop)
   {
     ..Здесь получаем некоторые данные и копируем в список, например QVector
 
   }
}
//---------------------------------------------------------------------------
void CThr::s_OnTimer(void)
{
  //..... Здесь по таймеру удаляем некоторые данные из QVector
  // Нужны ли здесь критические секции :
EnterCriticalSection (&Sect);
  ... удаление данных

LeaveCriticalSection (&Sect);



}

Вопрос для Таймера приложением создается и запускается отдельный поток или же запуск происходит в моем потоке CThr? И нужны ли критические секции (во время добавления данных в список и удаления по таймеру из списка)?
Записан
BRE
Гость
« Ответ #3 : Февраль 21, 2011, 09:08 »

Вопрос для Таймера приложением создается и запускается отдельный поток или же запуск происходит в моем потоке CThr?
Таймер запуститься в твоем потоке.
Для того, что бы он заработал, необходимо запустить обработку очереди событий в самом потоке.

И нужны ли критические секции (во время добавления данных в список и удаления по таймеру из списка)?
Если будет запущена обработка событий, то никакие критические секции не нужны, потому что два этих действия (добавление и очистка) будут разнесены.
Записан
Andrew Vladoff
Гость
« Ответ #4 : Февраль 21, 2011, 10:00 »

Цитировать
Если будет запущена обработка событий, то никакие критические секции не нужны, потому что два этих действия (добавление и очистка) будут разнесены

Т.е. код который я привет (если убрать критические секции) написан правильно, косяков не должно быть?
Записан
BRE
Гость
« Ответ #5 : Февраль 21, 2011, 10:12 »

Т.е. код который я привет (если убрать критические секции) написан правильно, косяков не должно быть?
Не все здесь видно, набросаю свой код:
Код
C++ (Qt)
CThr::CThr() : ...
{
moveToThread( this );
}
 
void CThr::run(void)
{
 // Объявляем Таймер
  QTimer timer;
  connect( &timer, SIGNAL(timeout()), SLOT(s_OnTimer()), Qt::DirectConnection ); // укажим принудительно прямое подключение
  timer.start(1000);
 
  QEventLoop loop;
 
  //--------- чтение пакетов и заполнение списка
 while (!flStop)
  {
    ..Здесь получаем некоторые данные и копируем в список, например QVector
    loop.processEvents();    // прокрутили очередь сообщений + таймеры
  }
}
 
Записан
twp
Гость
« Ответ #6 : Февраль 22, 2011, 15:14 »

Код
C++ (Qt)
void CThr::run(void)
{
 // Объявляем Таймер
  QTimer timer;
  connect( &timer, SIGNAL(timeout()), SLOT(s_OnTimer()), Qt::DirectConnection ); // укажим принудительно прямое подключение
  timer.start(1000);
 
  QEventLoop loop;
 
  //--------- чтение пакетов и заполнение списка
 while (!flStop)
  {
    ..Здесь получаем некоторые данные и копируем в список, например QVector
    loop.processEvents();    // прокрутили очередь сообщений + таймеры
  }
}
 
имхо можно обойтись без QEventLoop, а обработку сообщений сделать через int QThread::exec() тогда просто:
Код
C++ (Qt)
void CThr::run(void)
{
  QTimer timer;
  connect( &timer, SIGNAL(timeout()), SLOT(s_OnTimer()), Qt::DirectConnection );
  timer.start(1000);
 
  exec();
}
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Февраль 22, 2011, 15:23 »

Код
C++ (Qt)
 while (!flStop)
  {
    ..Здесь получаем некоторые данные и копируем в список, например QVector
    loop.processEvents();    // прокрутили очередь сообщений + таймеры
  }
}
 
В большинстве случаев вероятно потребуется флажок
Код
C++ (Qt)
loop.processEvents(QEventLoop::WaitForMoreEvents);
 
Иначе нитка будет крутиться вхолостую. Хотя конечно, перекрывать стандартный exec (неск строчек) или нет - дело вкуса
Записан
bass667
Гость
« Ответ #8 : Январь 30, 2012, 22:22 »

Здравствуйте. Использую такой же код, только вот проблема - функция по таймеру вызывается не в новом потоке, а в старом (основном). Почему так может быть?
Записан
mutineer
Гость
« Ответ #9 : Январь 30, 2012, 22:51 »

Здравствуйте. Использую такой же код, только вот проблема - функция по таймеру вызывается не в новом потоке, а в старом (основном). Почему так может быть?

Какой из приведенных версий кода ты пользуешься?
Записан
bass667
Гость
« Ответ #10 : Январь 31, 2012, 12:04 »

Все варианты попробовал.

Всё, разобрался.
Я всё перепутал, всё правильно, поток создаётся, всё запускается. Если соединять сигнал со слотом с параметром Qt::DirectConnection, то всё работает правильно. Без этого параметра (т.е. с параметром по умолчанию) при блокировке основного потока, во втором потоке функция по таймеру переставала вызываться.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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