c++ - std::map::find 和 std::map::end 很奇怪
问题描述
所以基本上几个小时前,我正在做我的项目,而我根本没有接触过的东西无缘无故地坏了。这段代码:
CFilesystem::working_directory_t &CFilesystem::GetThreadDirectories( )
{
const auto dwThread = GetCurrentThreadId( );
const auto pSearch = _ThreadDirectories.find( dwThread );
volatile auto b = pSearch == _ThreadDirectories.end( );
if ( pSearch == _ThreadDirectories.end( ) )
{
_ThreadDirectories.insert( std::pair< DWORD, working_directory_t >( dwThread, working_directory_t( ) ) );
return GetThreadDirectories( );
}
return pSearch->second;
}
struct working_directory_t
{
std::string strWorkingDirectory;
std::stack< std::string > _DirectoryStack;
working_directory_t( ) = default;
void StoreCurrentWorkingDirectory( );
void RestoreWorkingDirectory( );
};
std::map< DWORD, working_directory_t > _ThreadDirectories { };
不想再工作了。运行时,变量如下所示: 无论出于何种原因,变量 b 的计算结果为 false,即使 pSearch 明显等于 end,如图所示。如果我将黄色箭头拖到 if 语句中以执行插入到 _ThreadDirectories 中的代码,则会引发如下异常:
我已经尝试重建、重新启动 Visual Studio 2019 和我的 PC。我尝试过内联 CFileSystem 声明而不是外部化它以查看这是否会有所作为,但它没有。我不知道发生了什么,我会很感激任何帮助。提前致谢。
解决方案
首先,如果找不到线程 ID,该函数将调用自身。你不能只返回对插入值的引用吗?
其次,也是最重要的,如果多个线程访问同一个映射,它肯定需要一个互斥锁来使其线程安全。
我会实现这样的功能:
CFilesystem::working_directory_t &CFilesystem::GetThreadDirectories( )
{
const auto dwThread = GetCurrentThreadId( );
std::lock_guard<std::mutex> lock(mMutex);
const auto pSearch = _ThreadDirectories.find( dwThread );
if ( pSearch == _ThreadDirectories.end( ) )
{
_ThreadDirectories.insert( std::pair< DWORD, working_directory_t >( dwThread, working_directory_t( ) ) );
return _ThreadDirectories[dwThread];
}
return pSearch->second;
}
其中 mMutex 是在 CFilesystem 中定义的 std::mutex 对象。
我还将保护使用 _ThreadDirectories 的其他函数中对地图的访问。你有删除条目的功能吗?如果是这样,也可以在那里使用 lock_guard。
推荐阅读
- r - R:传递要执行的赋值语句列表和存储的赋值变量
- upgrade - Artifactory 升级失败,需要 postgres 9.5 -> 9.6 升级说明
- android - 如果我希望每次看到活动时都执行网络请求,应该使用哪种生命周期方法?
- javascript - Async/Await 和 Redux Thunks:调用 'dispatch' 是否隐式返回来自 thunk 的承诺?
- javascript - 创建一个简单的分数排行榜
- python - 同步代码的异步性能
- laravel - 升级存储中的 Wamp 图像后未显示 404 未找到
- c# - Can't sum up all Int32 field values
- spring - Spring Boot 2.0 OAuth2 客户端 - 跨会话获取不记名令牌
- c# - 如何避免自动映射器中的重复计算