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 &lt&lt m &lt&lt "|";
        

        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 错误?的主要内容,如果未能解决你的问题,请参考以下文章

C++ std::stringstream类

为啥 std::stringstream 在静态内联时不能默认构造?

相当于 %02d 与 std::stringstream?

std::stringstream 可以设置失败/坏位的方式?

是 包含时自动包含

将 std::string 转换回使用 std::stringstream << cv::Mat 生成的 cv::Mat