yleesun 发表于 2009-6-16 09:23:50

关于ACE_Svc_Handler

我声明一个继承至ACE_Svc_Handler的类:mainTask.其中有成员变量:std:vector<T> list;我在回调handle_input中向list中放入内容,在handle_output中从list中取,但是在handle_input中是放入成功了,但是在handle_output中取的时候,发现list中是有内容,但是内容不正确。不是在huandle_input时候放入的内容。
为什么list中的内容在handle_output中取不出来呢?

请高手帮助!!

winston 发表于 2009-6-16 10:00:26

贴上代码看看,否则只是猜测。
追踪代码,查看原因。
可能是线程冲突导致

yleesun 发表于 2009-6-16 10:27:01

类的声明:
class MainTask :public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
{
        typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> super;

public:
        MainTask () : notifier_ (0, this, ACE_Event_Handler::WRITE_MASK)
        {}

        virtual int open (void * = 0);

        virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);

        virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);

public:
       // 在handle_input函数中向此列表中插入数据,在handle_output函数中取出。
        std::vector<sFesRawDataReq*>                m_reqlist;

private:

        ACE_Reactor_Notification_Strategy        notifier_;
       
        ACE_Mutex                                                        m_mutex;
};

// handle_input在此函数中向m_reqlist中插入内容。此处跟踪没有出问题。
int MainTask::handle_input (ACE_HANDLE)
{
       
        char buf;
        // 接收主程序数据请求,并放入请求队列:m_reqlist
        ssize_t recv_cnt = this->peer ().recv (buf, sizeof (buf) - 1);
        if (recv_cnt > 0)
        {
                buf = '\0';
                sFesRawDataReq *pdata = new sFesRawDataReq;
                pdata = (sFesRawDataReq*)buf;
               
                // 操作之前先锁定
                m_mutex.acquire();
                // 检查请求列表,始终只维持一个IP的一个请求。如果有重复IP,则删除前一个请求。
                std::vector<sFesRawDataReq*>::iterator iter =m_reqlist.begin();
                int flag = 0;
                for (iter;iter != m_reqlist.end();iter++)
                {

                        sFesRawDataReq *ptemp = (*iter);
                        if (ACE_OS::strncmp(ptemp->ip,pdata->ip,ACE_OS::strlen(pdata->ip)) == 0)
                        {       
                                m_reqlist.erase(iter);
                                iter = m_reqlist.begin();
                                m_reqlist.push_back(pdata);
                                flag = 1;
                                break;
                               
                        }
                       
                }
               
                // 此请求为新请求,放入队列。
                if (flag == 0)
                {
                        m_reqlist.push_back(pdata);
                }
                // 释放锁
                m_mutex.release();
                return 0;
        }
       
        return 0;
}
// 取m_reqlist中的内容。但是取出的是乱码。
int MainTask::handle_output (ACE_HANDLE)
{
       
        ACE_Message_Block *mb;

        ACE_Time_Value nowait (ACE_OS::gettimeofday ());
        while (-1 != this->getq (mb, &nowait))
        {
                // 消息内容长度
                size_t len = mb->length();

                // 消息块内容
                char *buff = mb->rd_ptr();
                sFesRawDataInfo *pdata = (sFesRawDataInfo*)buff;

                std::vector<sFesRawDataReq*>::iterator iter = m_reqlist.begin();
                // 读取请求之前先锁定
                m_mutex.acquire();

                //判断此次读取的记录是否为主程序请求数据,如果是,则发送给主程序。
                for (iter;iter != m_reqlist.end();iter++)
                {
// 此处显示取出的是乱码
                        sFesRawDataReq* preq = (sFesRawDataReq*)*iter;
                        if (preq->id == pdata->id)
                        {
                                size_t send_cnt = this->peer ().send (mb->rd_ptr(), len);

                                if (send_cnt == -1)
                                {
                                        ACE_ERROR ((LM_ERROR,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("send")));
                                }
                                else
                                {
                                       
                                        // 更新消息块读指针
                                        mb->rd_ptr (ACE_static_cast (size_t, send_cnt));

                                }
                               
                                mb->release ();
                        }
                }
                // 释放锁
                m_mutex.release();
        }
       
        return 0;
}

[ 本帖最后由 yleesun 于 2009-6-16 10:34 编辑 ]

winston 发表于 2009-6-16 13:02:13

if (ACE_OS::strncmp(ptemp->ip,pdata->ip,ACE_OS::strlen(pdata->ip)) == 0)
                        {      
                              m_reqlist.erase(iter);
                              iter = m_reqlist.begin();
                              m_reqlist.push_back(pdata);
                              flag = 1;
                              break;
                              
                        }
vector迭代器循环中,不要进行删除操作。因为删除操作导致其后的迭代器全部失效。

yleesun 发表于 2009-6-16 13:57:42

谢谢楼上先!
我试了下,不删除,问题还是存在!!

winston 发表于 2009-6-16 15:27:36

1、检查进入vetor的代码,查看内存是否正常
2、取出时候,看看内存是否有问题。
这种问题,追踪一下就应该可以得到答案了。

yleesun 发表于 2009-6-16 19:38:40

这里我用ACE_Message_Queue<ACE_NULL_SYNCH> 没有问题。我换成用普通数组,也是出现同样的问题,非常迷惑!难道成员变量只能用ACE提供的数据结构吗?

winston 发表于 2009-6-16 20:02:07

一定是你的代码问题。如果你能提供代码工程 - 上传上来。大家帮你分析分析。
ACE兼容各种数据结构。

yleesun 发表于 2009-6-17 16:54:39

问题解决了。原因是没有把数据从接收缓冲区拷贝出来。
页: [1]
查看完整版本: 关于ACE_Svc_Handler