Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
1

Синхронизация итераций между потоками

06.08.2014, 12:04. Показов 2007. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день. Сразу скажу, что облазил все доступные мне офф. доки по Qt и полгугла, но не нашел необходимых мне средств в Qt.

Задача такая: в нескольких потоках параллельно идет обработка кусков одного большого массива данных. В каждом потоке крутится цикл, в котором и идет эта обработка. Цикл важен, т.к. счетчик цикла указывает на тип текущего разбиения массива (что предотвращает коллизии). После каждой итерации цикла потоки должны синхронизироваться.

Из доступных примитивов в Qt я нашел только QWaitCondition, QMutex и QSemaphore. Из них, не найдя ничего лучше, я нагородил вот такую вот штуку:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ThreadWorker : public QObject
{
   //....
    void Work(int count, QMutex *_m, QSemaphore *_s, QWaitCondition *_wc, int _n)
    {
        for (int i = 0; i < count; ++i)
        {
            //....обработка....
 
            //Thread synchronization:
            _m->lock();               //Мьютекс m лично мне не нужен, но он нужен в QWaitCondition
            _s->release(1);             //Каждый поток инкрементирует ресурсы в семафоре
            if (_s->tryAcquire(_n)) {   //Используем кол-во ресурсов в семафоре, как проверку на завершения 
                  _wc->wakeAll();        //итерации всеми потоками. Один из счастливчиков пробудит остальных
            }                              // (_n - общее количество потоков)
            else _wc->wait(_m);        //Ждем пробуждения от одного из потоков
            _m->unlock(); 
        }
 
        emit Finished(id);
    }
}
Но выглядит это как то совсем не элигантно... И мне хотелось бы знать, может есть что-то в Qt, способное мне помочь???
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.08.2014, 12:04
Ответы с готовыми решениями:

Связь между потоками
Пытаюсь реализовать змейку на qt и вот остановился на моменте связи между основным и другим...

Сигналы между потоками
Подскажите, что не так с моими изысканиями в использовании потоков в Qt Проблема в том, что не...

Передача данных между потоками
Изучаю многопоточные приложения. Есть 2 потока, в основном окне есть поле ввода, надо как-то...

Передача сигналов между потоками
у qt есть какието ограничения на передачу сигналов из дочернего потока в главный? пишу { ...

4
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
06.08.2014, 12:36 2
1) Почему бы сразу не разбить массив на нужное количество частей, отдельно из обработать, а потом склеить? Это будет быстрее чем постоянно синхронизировать потоки.

2) Ваша реализация вполне нормальная, и даже простая. Не знаю что вы хотите получить от Qt, который дает лишь обертки над стандартными примитивами синхронизации.
Как я уже сказал в пункте 1, Qt может предложить вам разве что из QtConcurrent::map()
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.08.2014, 21:01 3
Цитата Сообщение от RazrFalcon Посмотреть сообщение
1) Почему бы сразу не разбить массив на нужное количество частей, отдельно из обработать, а потом склеить? Это будет быстрее чем постоянно синхронизировать потоки.
Зависит от того ка обрабатываются элементы массива, если за одно тоже время, то быстрее, а если за разное скорее всего медленнее будет.

Добавлено через 2 минуты

Не по теме:

C++ (Qt)
1
QMutex *_m,
Кто вас учил ставить подчеркивание в начале имен переменных? Это плохой стиль...



Цитата Сообщение от RazrFalcon Посмотреть сообщение
Qt может предложить вам разве что из QtConcurrent::map()
Ну так по-моему задача как раз для него.
1
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
06.08.2014, 21:06 4
Цитата Сообщение от Avazart Посмотреть сообщение
если за разное скорее всего медленнее будет
Ну это да, но ТС все равно ждет после каждого n прохода...
0
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
10.08.2014, 21:58  [ТС] 5
Парни, спасибо, с этим проблем нет больше, но появилась новая проблема.

После закрытия приложения gui закрывается, но что-то продолжает висеть в диспетчере задач (винда). Причем без какой-либо активности. Также в application output не выводится сообщение "приложение.exe exited with code 0". Если запускаю только один поток (помимо главного) то все хорошо завершается, но с более чем 1 получается такая штука.

Проверял деструкторы - вызываются все. В том числе отслеживал с помощи qDebug() вызов конструкторов и деструкторов объектов, которые запускаются в потоках. После закрытия проги доходит до main.cpp и строки return a.exec();

p.s. для закрытия потоков - сперва их останавливаю. Потом, когда от них приходит сигнал о завершении (самописный) - вызываю thread->quit() и thread->wait(); и разрушаю как объекты, так и потоки.
0
10.08.2014, 21:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.08.2014, 21:58
Помогаю со студенческими работами здесь

Передача данный между потоками
Доброго времени суток. Вопрос следующий! Предположим имеется 2 пока (GUI и второй). Возможно ли...

Передача данных между потоками
Подскажите пожалуйста как передать объект между потоками через сигнал-слот? у меня выдает следующее...

Сигналы и слоты между потоками
Имеется окно с кнопкой, и класс который делает &quot;невероятно сложные&quot; вычисления... соединяем сигнал...

Обращения между потоками (сигналами) падает
Приветствую всех, у меня есть программа, которая просто копирует файл из одного места в другое, но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru