Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Потоки в Qt и использование boost::mutex


Автор: Elfet 9.5.2010, 18:44
Всем привет! 

Добавил в свою программу блокировку данных при помощи мьютекса из boost::mutex. Но теперь стал интерфейс сильно тормозить.
Вот как это у меня работает:
Код

void MyThread::run()
{
    is_runing = true;

    boost::shared_ptr<Solver> solver = sflib->GetSolver().lock();

    while(solver->Iteration(i))
    {
        emit Progress(i);

        if(!is_runing)
        {
            return;
        }
    }

    emit Finished();
}

Мьютекс находится в классе Solver, блогирую я его тут:
Функция Solver::Iteration(int&p):
Код

bool Solver::Iteration(int &percent)
{
    // Блокировка
    boost::mutex::scoped_lock lock(mutex);
...

И в функции обновления интерфейса (она соединена со сигналом emit Progress(i))
Код

connect(iterationThread, SIGNAL(Progress(int)), this, SLOT(ProgressIteration(int)));

...

void MainWindow::ProgressIteration(int value)
{
    boost::shared_ptr<Solver> solver = sflib->GetSolver().lock();
    boost::mutex::scoped_lock lock(solver->mutex);

...


Интерфейс сильно тормозит.  Можно ли что-нибудь сделать что бы он не тормозил? Заранее спасибо!


Автор: borisbn 10.5.2010, 09:46
Ты блокируешь функции обработки и отрисовки целиком. Попробуй определить место, где обработка и отображение обращаются к одним и тем же данным, и заблокировать только это место. А ещё лучше перед использованием данных в отображении заблокировать mutex, скопировать необходимые данные во временные переменные, разблокировать mutex и спокойно отображать сохранённые копии. При этом блокировать можно всю функцию обработки

Автор: Elfet 10.5.2010, 18:33
А если данные очень большие? Я отображаю сетку (10тыс. - 100тыс. узлов) и копировать её целиком достаточно проблематично. Дольше всего работает естественно функция отрисовки сетки в интерфейсе. В библиотеке же дольше всего итерации по этой сетки. Есть ли какие-нибудь ещё альтернативы? 

Кстати хотел спросить кое-что ещё: я собираю библиотеку, которая должна потом использоваться в многопоточном приложении и хочу главный класс-интерфейс этой библиотеки разместить в синглтоне (потокобезопасном). Нормально ли это? 

Автор: borisbn 11.5.2010, 09:58
Цитата(Elfet @  10.5.2010,  18:33 Найти цитируемый пост)
Я отображаю сетку (10тыс. - 100тыс. узлов)

неужели на каждом шаге обработки необходимо отображать все данные? Может стоит перекинуть часть обработки графика в поток (например подготовить там список QPoint'ов и скопировать его в интерфейсный поток). Может стоит отображать не на каждом шаге, а, например, каждый десятый.

Цитата(Elfet @  10.5.2010,  18:33 Найти цитируемый пост)
 главный класс-интерфейс этой библиотеки разместить в синглтоне (потокобезопасном). Нормально ли это? 

синглтон - зло. Это правило, из которого всегда есть исключения, однако по собственному опыту неоднократно в этом правиле убеждался. Лучше заблокировать данные на момент их копирования, чтобы обеспечить потокобезопасность.

Автор: Elfet 11.5.2010, 12:57
Данные нужно бы отображать на каждом шаге - иначе не понятно как решение распространяться.  Странно вот что мне если я соединяю с помощью Qt::BlockingQueuedConnection:
Код

connect(iterationThread, SIGNAL(Progress(int)), this, SLOT(ProgressIteration(int)), Qt::BlockingQueuedConnection);

То интерфейс перестаёт тормозить.  smile  smile 

Автор: chaos 11.5.2010, 13:11
офтоп: а зачем Вам boost::mutex? Ведь есть же QMutex

Автор: Elfet 11.5.2010, 14:01
chaos, мы в библиотеке не используем Qt. Qt только в интерфейсе.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)