C ++ передает функцию, возвращающую структуру в пул потоков, создает ошибки c результатов и "зависает" - PullRequest
0 голосов
/ 05 августа 2020

Я программист-любитель, изучающий 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;
}

1 Ответ

0 голосов
/ 05 августа 2020

HTags Tags в ExtractTrackTags подозрительно выглядит как глобальная переменная. Если это действительно так, то это причина ваших проблем. Уменьшите область действия до ExtractTrackTags (чтобы у каждого потока была своя собственная изолированная копия), и проблемы должны разрешиться сами собой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...