std::locale/std::facet临界区

14
出于好奇,我曾经见过像 boost::to_lower 这样的函数性能下降,因为在分配懒惰 facet 时使用了 std::use_facet 中的 CriticalSection。据我记得,全局锁定区域存在一个错误,但根据 Stephan Lavavej 的说法,这个问题在 VS2013 中已经修复了。然而,昨天我看到 facet 上的这个锁杀死了服务器的性能,所以我想我可能混淆了两个不同的问题。
但是,首先,为什么要在懒惰 facet 周围加上 CriticalSection?显然它会破坏性能。为什么他们没有采用一些可升级的锁或指针上的原子操作来解决这个问题呢?

我有同样的问题... - user541686
1
@Mehrdad,如果你真的想要答案,最好向VC++团队提问或在Microsoft Connect上开一个工单。 - kreuzerkrieg
你能添加一个链接,指向Stephan Lavavej在VS2013中修复了它的地方吗? - user4442671
3年前,去找一下吧...我会尝试寻找链接。 - kreuzerkrieg
1
@Frank,由于微软取消了Connect并改为Collaborate,几乎不可能找到这个问题。最接近的结果在这里https://social.msdn.microsoft.com/Forums/vstudio/en-US/b049dbda-c115-410b-b5d8-513f727baf4d/can-stl-streams-run-concurrently-?forum=vcgeneral和这里https://blogs.msdn.microsoft.com/vcblog/2012/06/15/stl-bugs-fixed-in-visual-studio-2012/. Connect issue: 492561 - kreuzerkrieg
1个回答

5

MSVC++中的std::locale是基于底层C函数setlocale实现的。这会涉及到全局状态,因此必须受到锁的保护。

不幸的是,更改数据结构的锁定语义是一种破坏ABI的变化,因此我们暂时无法做太多事情。


1
嗯,你有实际地逐步执行代码吗?如果我只是运行 for (;;) { std::use_facet<std::numpunct<char> >(loc); } 并逐步执行它,我会看到在 use_facet 内部获取和释放锁,而没有任何明显的与基于 C 的区域设置相关的交互。因此,除非我漏掉了什么,否则我不确定这个答案是这个问题的正确答案... - user541686
1
@Mehrdad:如果你这样做,facets 将被缓存,因此不需要进入 setlocale。但不幸的是,同一把锁用于保护缓存的 facets 表本身 :/ - Billy ONeal
是的,我想问题是...为什么他们要这样设计呢?这只是他们忽视了什么,还是背后有更多的故事? - user541686
2
不知道,我猜你得问Dinkumware。我认为这些东西在过去十年里都没有被涉及 :/ - Billy ONeal
@kreuzerkrieg 不是很准确。与 Dinkumware 合作的标准库解散早在我加入 VC++ 团队之前就已经发生了 :) - Billy ONeal
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接