Добрый день
Почти каждая тема "многопоточности" сваливается в проблемы синхронизации и/или классы QtConcurrent. Вот стало интересно - а можно как-то без всего этого, чисто на слот/сигнал?
У нас есть N задач которые мы хотим скормить какому-то числу ниток (обычно = числу ядер). При этом обычный ф-ционал: остановить, продолжить, отменить. Принципиально не используем никаких примитивов синхронизации, даже любимых мною атомиков. И делаем "по-богатому": задача стартовала/закончилась- сигнал в UI, все отмены/продолжения - тоже испускаем сигналы. Конечно так будут накладные расходы, но мы считаем задачи у нас достаточно жирные (хорошие доли секунды и больше). В общем, за скоростью не гонимся
Чтобы юзать надо создать нужные слоты. Пример
C++ (Qt)
// создаем "бригаду"
CControl * ctl = new CControl(QThread::idealThreadCount()); .
// слот который считает, (только он выполняется в рабочих нитках, все остальные в главной)
ctl->Connect2Calc(this, &CTestWin::SlotCalc);
// слот скармливающий очередную задачу
QObject::connect(ctl, &CControl::SignalTaskGet, this, &CTestWin::SlotGetTask);
// слот "задача началась"
QObject::connect(сtl, &CControl::SignalTaskBegin, this, &CTestWin::SlotTaskBegin);
// слот "задача сделана"
QObject::connect(ctl, &CControl::SignalTaskDone, this, &CTestWin::SlotTaskDone);
// слот "нитка не имеет больше задач"
QObject::connect(ctl, &CControl::SignalNoTask, this, &CTestWin::SlotNoTask);
// отслеживает останов, пуск, отмена и готово
QObject::connect(ctl, &CControl::SignalStateChanged, this, &CTestWin::SlotStateChanged);
// погнали считать
ctl->Go();
Окончание ловим в SlotStateChanged. В аттаче пример с UI (pro файл имеется)
Это все, благодарю за внимание