Как организовать многопоточную обработку файлов (открытие, сбор данных, закрытие) из массива QFileInfoList?
Я нашел пример кода, где вы можете просто поместить его в 1 отдельный поток. И если например файлов будет 20 и более, и вам нужно разделить их, например, на 4 потока.
dir.cd(pathFolder);
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
QStringList nameFilter;
nameFilter << "*.txt";
QFileInfoList list = dir.entryInfoList(nameFilter);
Это то, что происходит при обработке. Он просто читает 1 строку, проверяет совпадение и добавляет ее в QTableWidget.
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
QFile file(fileInfo.filePath());
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line = in.readLine();
if(line.indexOf("str")!=-1)
{
ui->listWidget_ps->addItem(fileInfo.fileName());
}
}
}
Самый быстрый способ сделать то, что вы хотите, без существенного изменения кода - воспользоваться openmp. Для этого проделываем следующие шаги:
"Включаем" openmp, для этого добавляем в .pro файл следующее:
QMAKE_CXXFLAGS += -fopenmp
LIBS += -fopenmp
после этого может понадобиться очистить проект и вручную дернуть qmake
Объявляем сигнал для доставки найденных имен файлов из рабочих потоков в основной:
signals:
void sendFileName(QString fileName);
Заменяем в цикле добавление строки в QListWidget
на emit этого сигнала:
if(line.indexOf("str")!=-1)
emit sendFileName(fileInfo.fileName());
Соединяем сигнал с методом добавления строки в лист (я делал это в конструкторе окна тестовой программы, но по сути надо сделать это один раз где-то перед испусканием сигнала)
connect(this, &MainWindow::sendFileName, ui->listWidget_ps, QOverload<const QString &>::of(&QListWidget::addItem));
Обратите внимание на конструкцию QOverload
, addItem
не является слотом, из-за этого "старый" синтаксис соединения не сработает. Также addItem
имеет перегрузки, в которые не умеет "обычный новый" синтаксис, чтобы подружить его с перегруженными методами, используется QOverload
.
Командуем openmp выполнить наш цикл в многопоточном режиме:
#pragma omp parallel for
for (int i = 0; i < list.size(); ++i) {
...
По моим тестам прирост производительности примерно в 4.5 раза на массиве данных в 1000 файлов.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Столкнулся с такой проблемой: нужно удалить N сообщений на канале в дискордеКак это сделать?
какой алгоритм кластеризации и меру похожести для изображений подскажите или порекомендуете? какие этапы для этого нужно сделатьбуду благодарен...