Я программист-любитель, изучающий C ++ и многопоточность. После некоторых проблем с началом моей первой попытки создания пула потоков. Спасибо за предложения, которые я получил на этом форуме. Я дошел до того, что принципалы работают.
Я пытаюсь извлечь 20 тегов из файла c musi (FLA C). В одном сеансе может быть 7000 файлов для сканирования.
Каждое извлечение - это отдельное действие, и конечный результат (будущее) помещается в вектор структур для последующей обработки.
I используйте Code :: Blocks 20.3 и MinGW 17.1 на компьютере Windows 10 Pro.
Проект компилируется без ошибок и предупреждений.
Только с одним потоком приложение работает отлично.
Однако, когда я использую 2 потока в пуле, функция «ExtractTrackTags» возвращает значения errati c в структуре, которую нужно вернуть, и часто приложение «зависает».
Я подозреваю, что структура, которую я передаю, либо недостаточно жива, либо используется в пуле потоков. Я попытался использовать вектор пустых структур (очищенный после того, как все файлы будут готовы), но это не помогло. Кроме того, когда количество потоков в пуле превышает количество загружаемых мной файлов, приложение «зависает».
Я надеюсь, что кто-то может помочь мне в этой работе. Спасибо.
Ruud.
--- Заголовок ---
#ifndef TRACKTAGS_H_INCLUDED
#define TRACKTAGS_H_INCLUDED
//-
#include "Threadpool.h" // .h and .cpp from https://codereview.stackexchange.com/questions/221626/c17-thread-pool
#include <iostream> // Required for comdef.h
#include <comdef.h> // LPWSTR conversion
#include <filesystem>
#include <string>
#include <vector>
#include <sstream> // For threadID
#include <thread> // For threadID
#include <wx/string.h>
//-
struct TagsStruct
{
bool OK;
wxString ThreadID; // For testing purposes only
wxString PlayTime;
wxString AlbumArtist;
wxString Collection;
// etc...
};
//-
std::vector<TagsStruct> ExtractMultiTags(std::vector<wxString> vwsFiles, wxString wsCol);
//-
#endif // TRACKTAGS_H_INCLUDED
--- Функция извлечения, вызывающая "ExtractTrackTags" через пул потоков ---
std::vector<TagsStruct> ExtractMultiTags(std::vector<wxString> vwsFiles, wxString wsCol)
{
// Clear existing Vector of Futures
vTrackTags.clear();
// Get max threads
unsigned int th_cnt{std::thread::hardware_concurrency()};
th_cnt = 1; // For testing purposes only
Thread_Pool Pool(th_cnt);
std::vector<std::future<TagsStruct>> Futures;
for(auto &aTrack : vwsFiles)
{
TagsStruct TSp = TagsStruct();
Futures.push_back(Pool.execute(ExtractTrackTags, TSp, aTrack, wsCol));
}
for (auto &Fut : Futures)
{
TagsStruct TSf = TagsStruct();
TSf = Fut.get();
vTrackTags.push_back(TSf);
}
return vTrackTags;
}
--- Извлечь из файла трека ---
static TagsStruct ExtractTrackTags(TagsStruct TagLine, wxString wsFile, wxString wsCollection)
{
// Convert std::string to LPWSTR
LPWSTR wsFileName{ConvertString(wsFile)};
// Load the tags
TagsLibrary_Load(Tags, wsFileName, ttAutomatic, TRUE);
if (TagsLibrary_Loaded(Tags, ttAutomatic))
{
/* Extract the Audio Attributes */
TAudioAttributes Attribs;
if (!TagsLibrary_GetAudioAttributes(Tags, TAudioType::atAutomatic, &Attribs))
{
TagLine.PlayTime = std::__cxx11::to_string(Attribs.PlayTime);
// etc...
}
/* Extract the named TAGs*/
//AlbumArtist
std::wstring ws05(TagsLibrary_GetTag(Tags, ConvertString("ALBUMARTIST"), ttAutomatic));
TagLine.AlbumArtist << std::string(ws05.begin(), ws05.end());
// etc...
}
else
{
TagLine.OK = false;
wxString msg = "\tNo tags found in:\n" + wsFile ;
wxMessageBox(msg, _("ERROR..."));
}
return TagLine;
}