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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не перезапускать поток  (Прочитано 4761 раз)
RedDog
Гость
« : Февраль 02, 2012, 08:40 »

Как сделать нечто подобное:

Код
C++ (Qt)
class Searcher;
class MyThread : public QThread
{
private:
   Searcher *_searcher;
   void *pBuf;
   qint64 bufSize;
   bool stop;
public:
   void run();
   void setScanBuf(void *buf, qint64 size)
   {
        pBuf = buf;
        bufSize = size;
   }
};
 
Код
C++ (Qt)
void MyThread::run()
{
   while (!stop)
   {
        bool found = _searcher->Search(pBuf, bufSize);
        emit result(found);
        waitForSomeMutex(someMutex);
   }
}

т.е. создается класс потока, в него передается указатель на буфер для поиска, запускается поток, которй что то ищет.
Буферов, в которых надо искать очень много, и что бы избежать оверхеда при перезапуске потоков (их  >1 будет) надо
дождаться некоего сигнала из главного потока, что буфер сменен и можно продолжать дальше уже с новым буфером.
Т.е. через чего лучше организовать waitForSomeMutex(someMutex) ?
Записан
alexman
Гость
« Ответ #1 : Февраль 02, 2012, 08:55 »

Можно, через QEventLoop попробовать.
Записан
RedDog
Гость
« Ответ #2 : Февраль 02, 2012, 09:01 »

Это как? Ни разу с ним не работал, плохо представляю.
Записан
alexman
Гость
« Ответ #3 : Февраль 02, 2012, 09:09 »

Да сам не пробовал. Главное выяснить: не будет ли грузить процессор int QEventLoop::exec ( ProcessEventsFlags flags = AllEvents ).

Код:
class Searcher;
class MyThread : public QThread
{
     Q_OBJECT
    
private:
    QEventLoop *_eventLoop;
    Searcher *_searcher;
    void *pBuf;
    qint64 bufSize;
    bool stop;

public:
    void run();
    void setScanBuf(void *buf, qint64 size)
    {
         pBuf = buf;
         bufSize = size;
    }

    void seach()
    {
          emit exitLoop();
    }

signals:
    void exitLoop();
};

Код:
void MyThread::run()
{
    QEventLoop eventLoop;
    connect(this, SIGNAL(exitLoop()), &eventLoop, SLOT(quit()), Qt::QueuedConnection);

    while (!stop)
    {
         eventLoop.exec();

         bool found = _searcher->Search(pBuf, bufSize);
         emit result(found);
    }
}

UPDATE: RedDog, немного поправил. Должно работать.
« Последнее редактирование: Февраль 02, 2012, 10:12 от alexman » Записан
alexman
Гость
« Ответ #4 : Февраль 02, 2012, 09:10 »

Еще не забудь, что, возможно, некоторые данные надо мьютексом закрыть.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Февраль 02, 2012, 09:42 »

Код
C++ (Qt)
void MyThread::run()
{
   while (true)
   {
        void * pBuf;
        qint64 bufSize;
        mSemaphore.acquire();   // ждем на семафоре если нет буферов
        if (stop) return;
        else {
         QMutexLocker locker(&theBufMuteх);    // захватываем контейнер буферов
         pBuf = GetBuf(&bufSize);             // извлекаем буфер из контейнера (takeAt)
         if (!pBuf) continue;                 // подстраховались
         if (pBuf == theEndOfJob) return;      // часто так лучше чем stop
        }
        bool found = _searcher->Search(pBuf, bufSize);
        emit result(found);
   }
}

Записан
RedDog
Гость
« Ответ #6 : Февраль 02, 2012, 13:11 »

alexman, не до конца понял...
главный поток работает по принципу:
Код:
for (int i = 0; i < threadCount; ++i)
_treads[i]->start();
после того как все отработали (счетчик стоит автодекрементый на сигнал found(bool)), тормозим все и запускаем заново:
Код:
for (int i = 0; i < threadCount; ++i)
{
   _treads[i]->exit(0);
   _treads[i]->wait();
   _treads[i]->setScanBuf(pBuf, bufSize);
   _treads[i]->start();
}
тогда с QEventLoop получается следующее:

Код:
for (int i = 0; i < threadCount; ++i)
{
//   _treads[i]->exit(0); <== выкидываем
//  _treads[i]->wait(); <== выкидываем
   _treads[i]->setScanBuf(pBuf, bufSize);
   _treads[i]->seach(); << == добавляем
//   _treads[i]->start(); <== выкидываем
}
я идею правильно понял?
Записан
alexman
Гость
« Ответ #7 : Февраль 02, 2012, 14:51 »

Похоже...надо додумывать/пробовать. Только учти, что если exec еще не вызван, но вызван quit() - то в дальнейшем поток может зависнуть.
Записан
RedDog
Гость
« Ответ #8 : Февраль 02, 2012, 15:57 »

Да, так работает, только
Код:
eventLoop.exec();
перенес в конец цикла, иначе на нем все останавливается.
Хотя выгоды получил от этого всего %10 по скорости. Но зато проц не так сильно жрет теперь.
Мутексы не быстрее работать будут?
Записан
alexman
Гость
« Ответ #9 : Февраль 02, 2012, 16:10 »

Хотя выгоды получил от этого всего %10 по скорости.
Имеешь в виду прирост скорости от использования потоков?
Записан
RedDog
Гость
« Ответ #10 : Февраль 02, 2012, 16:32 »

Имеешь в виду прирост скорости от использования потоков?
нет, имел ввиду прирост скорости без перезапуска потоков.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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