std::stringstream 错误?
Posted
技术标签:
【中文标题】std::stringstream 错误?【英文标题】:std::stringstream bugs? 【发布时间】:2010-07-27 11:05:29 【问题描述】:我有自己的 DLL,它被注入到另一个进程中。在另一个进程中,DLL 通过boost::message_queue 向我的应用程序发送 IPC 消息。我正在使用 std::stringstream 来构造消息,如下所示:
class Client
...
private:
template <class T> void AddMessageParameter(const T &m)
_message << m << "|";
void SendMessage()
if (_mq && _message.str().length() < 1024)
// Do not send the same message again.
if (_mq_last_sent_message != _message.str())
_mq_last_sent_message = _message.str();
try
unsigned int tries = 0;
// Try send the message five times before giving up.
do
if (_mq->try_send(_mq_last_sent_message.c_str(), _mq_last_sent_message.length(), 0))
tries = 5;
else
::Sleep(128);
++tries;
while (tries < 5);
catch (...)
// TODO: Add log4cxx logging here for errors...
// Clear the message for a new one.
_message.seekp(0);
_message.clear();
_message.str(std::string());
private:
std::stringstream _message;
std::string _mq_last_sent_message;
boost::shared_ptr<boost::interprocess::message_queue> _mq;
;
在 DLL 中,其中一个函数不断发送以下消息:
AddMessageParameter("CLIENT__TABLE__PLAYER_BANKROLL");
AddMessageParameter(window_handle);
AddMessageParameter(seat);
AddMessageParameter(s);
SendMessage();
现在这会产生类似CLIENT_TABLE_PLAYER_BANKROLL|00211606|6|€1.28|
的消息。问题是,在每几千条消息中,第一个参数不会在那里添加,消息变成00211606|6|€1.28|
这是为什么呢?这是 std::stringstream 中的一些错误还是我做错了什么?
提前感谢您的帮助。
编辑:
问题解决了。这是一个线程安全问题。一个简单的互斥锁解决了这个问题。
【问题讨论】:
【参考方案1】:您的代码在尝试发送最长消息时失败。 因此,我假设消息目标读取速度不够快。
我认为您尝试 5 次的概念是有缺陷的,因为如果您的消息没有发送,您就会吞下它——您甚至没有处理这种严重的错误情况。 就我个人而言,我建议要么永远等待发送您的消息,要么构建一个大小合理的本地缓冲区供您使用 - 如果此缓冲区已满,那么您就永远等待。
我还建议您不要在不照顾它们的情况下吃掉所有异常。你默默地隐藏了严重的错误。
附带说明: 人们经常认为 std::string 有错误,或者操作系统有错误,甚至编译器有错误。 让我向您保证,这些人的指责经常是错误的,即使是最保守的悲观主义者也会说他们总是错了。 而那些正确的人可以在琐碎的程序中证明这一点。
请原谅我的傲慢。
【讨论】:
旁注的另一个 +1。以上是关于std::stringstream 错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::stringstream 在静态内联时不能默认构造?
std::stringstream 可以设置失败/坏位的方式?
将 std::string 转换回使用 std::stringstream << cv::Mat 生成的 cv::Mat