我正在使用一些现有代码反序列化存储在文本文件中的对象(我可能需要阅读数千万个这样的文件)。该文件的内容首先被读入一个wstring
,然后从中生成一个wistringstream
。在程序上运行 Very Sleepy 分析器显示它在以下调用堆栈中花费了大约 20% 的时间:
Mtxlock or RtlEnterCritialSection
std::_Mutex::_Lock
std::flush
std::basic_istream<wchar_t, std::char_traits<wchar_t> >::get
<rest of my program>
和类似的 std::_Mutex::_Unlock
。我正在使用 Visual C++ 2008。
查看 istream
,我看到它构造了一个 sentry
对象,它调用 _Lock
和 _Unlock
方法底层 basic_streambuf
。这反过来只是在与该缓冲区关联的 _Mutex
上调用 _Lock
和 _Unlock
。这些定义如下:
#if _MULTI_THREAD
// actually defines non-empty _Lock() and _Unlock() methods
#else /* _MULTI_THREAD */
void _Lock()
{ // do nothing
}
void _Unlock()
{ // do nothing
}
#endif /* _MULTI_THREAD */
看起来 _MULTI_THREAD 在 yvals.h
中设置为
#define _MULTI_THREAD 1 /* nontrivial locks if multithreaded */
现在,我知道永远不会有另一个线程试图访问这个缓冲区,但在我看来,在使用标准 iostream 时没有办法绕过这个锁定,这看起来既奇怪又令人沮丧。我错过了什么吗?有解决办法吗?
最佳答案
在项目属性、C/C++、代码生成中检查运行时库的值。如果是多线程的,就改成非多线程的版本。
在 Visual C++ 7.1 (!) 之后的任何版本中,你都不走运 as it's been removed ,并且您受困于多线程 CRT。
关于c++ - MSVC istream 实现锁定缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5822141/