c++ - 将结构返回到线程池的 C++ 传递函数会产生不稳定的结果并“挂起”
问题描述
我是一名爱好程序员,学习 C++ 和多线程。在我第一次尝试线程池时遇到了一些麻烦。感谢我在这个论坛收到的建议。我已经到了校长工作的地步。
我想要实现的是从音乐文件(FLAC)中提取 20 个标签。一个会话中可能需要扫描 7000 个文件。
每次提取都是一个单独的活动,最终结果(未来)被推送到结构向量以供以后处理。
我在 Windows 10 Pro 计算机上使用 Code::Blocks 20.3 和 MinGW 17.1。
该项目编译没有错误或警告。
只有 1 个线程,应用程序运行完美。
但是,当我在池中使用 2 个线程时,“ExtractTrackTags”函数会在要返回的结构中返回不稳定的值,并且应用程序通常会“挂起”。
我怀疑我正在传递的结构要么不够长,要么在线程池之间共享。我尝试使用空结构向量(在所有文件完成后清除),但这没有帮助。此外,当池中的线程数高于我提供的文件数时,应用程序“挂起”。
我希望有人可以帮助我完成这项工作。谢谢你。
路德。
---标题---
#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;
}
解决方案
HTags Tags
inExtractTrackTags
看起来可疑地像一个全局变量。如果情况确实如此,那么这就是您的问题的原因。将其范围缩小到ExtractTrackTags
(因此每个线程都有自己的独立副本),问题应该自行解决。
推荐阅读
- reactjs - React.useMemo 不更新数据
- javascript - 帖子格式(数组)ReactJs的问题
- python - 熊猫:在 2 行的连接字符串后删除行
- java - 在 tomcat 8 - CentOS 8 中部署系统 Spring boot
- odoo - 未找到公共网址(404 - 未找到)-Odoo10
- isabelle - 专注于 Eisbach 的新子目标
- batch-file - 将 findstr 设置为要引用的变量
- c# - 在 Xamarin.iOS 中检查蓝牙状态(开/关)
- css - Angular 无法在导航到嵌套路由时获取 CSS 文件
- node.js - 无法在 Azure 管道 (Nodejs) 上使用 pdf-parse 解析 PDF 流