Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Andrew Vladoff от Февраля 20, 2011, 20:51



Название: Таймер в потоке
Отправлено: Andrew Vladoff от Февраля 20, 2011, 20:51
В потоке обрабатываются определенные данные. Одной функцией потока данные добавляются в список, а по таймеру этот список очищается. Нужно ли использовать критические секции во время срабатывания таймера? Таймер запускается в этом же потоке или для него создается отдельный?


Название: Re: Таймер в потоке
Отправлено: BRE от Февраля 20, 2011, 20:59
Ты бы показал, как у тебя это все происходит.
Если я правильно тебя понял, то можно сделать так, что бы синхронизацией занималась сама очередь сообщений потока.


Название: Re: Таймер в потоке
Отправлено: Andrew Vladoff от Февраля 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? И нужны ли критические секции (во время добавления данных в список и удаления по таймеру из списка)?


Название: Re: Таймер в потоке
Отправлено: BRE от Февраля 21, 2011, 09:08
Вопрос для Таймера приложением создается и запускается отдельный поток или же запуск происходит в моем потоке CThr?
Таймер запуститься в твоем потоке.
Для того, что бы он заработал, необходимо запустить обработку очереди событий в самом потоке.

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


Название: Re: Таймер в потоке
Отправлено: Andrew Vladoff от Февраля 21, 2011, 10:00
Цитировать
Если будет запущена обработка событий, то никакие критические секции не нужны, потому что два этих действия (добавление и очистка) будут разнесены

Т.е. код который я привет (если убрать критические секции) написан правильно, косяков не должно быть?


Название: Re: Таймер в потоке
Отправлено: BRE от Февраля 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();    // прокрутили очередь сообщений + таймеры
  }
}
 


Название: Re: Таймер в потоке
Отправлено: twp от Февраля 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();
}
 


Название: Re: Таймер в потоке
Отправлено: Igors от Февраля 22, 2011, 15:23
Код
C++ (Qt)
 while (!flStop)
  {
    ..Здесь получаем некоторые данные и копируем в список, например QVector
    loop.processEvents();    // прокрутили очередь сообщений + таймеры
  }
}
 
В большинстве случаев вероятно потребуется флажок
Код
C++ (Qt)
loop.processEvents(QEventLoop::WaitForMoreEvents);
 
Иначе нитка будет крутиться вхолостую. Хотя конечно, перекрывать стандартный exec (неск строчек) или нет - дело вкуса


Название: Re: Таймер в потоке
Отправлено: bass667 от Января 30, 2012, 22:22
Здравствуйте. Использую такой же код, только вот проблема - функция по таймеру вызывается не в новом потоке, а в старом (основном). Почему так может быть?


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

Какой из приведенных версий кода ты пользуешься?


Название: Re: Таймер в потоке
Отправлено: bass667 от Января 31, 2012, 12:04
Все варианты попробовал.

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