rainfish 发表于 2008-11-28 17:48:31

关于定时器崩溃的问题

我想记录定时器任务的指针,如下操作

// 创建任务对象
      CTimerTask<TYPE>* pTask = new CTimerTask<TYPE>( 0 );
      ACE_ASSERT( pTask );
      
      if ( pTask == NULL )
      {
            ACE_ERROR( (LM_ERROR,
                ACE_TEXT ("<CTimerManager::regist_period_cycle_task> new start CTimerTask failed!\n")) );
            
            return -1;
      }

      

         pTask->m_fnTask = pFun;
         pTask->m_sTime = ACE_Time_Value(startTime);
         pTask->m_interval = ACE_Time_Value(cycleSecond, cycleMillisecond);
      pTask->m_stData.data = data;
      
      // 注册任务
      pTask->m_lID = m_timer.schedule( pTask, (void*)&(pTask->m_stData),
            pTask->m_sTime, pTask->m_interval );
      
      if ( pTask->m_lID <= 0 )
      {
            ACE_ERROR( (LM_ERROR,
                ACE_TEXT ("<CTimerManager::regist_single_task> schedule start time task failed(ID=%l)!\n"), pTask->m_lID) );

            delete pTask;
            pTask = NULL;
            return 0;
      }
       m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));

有时执行m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));时程序崩溃,提示访问越界,很纳闷,我只是保存一个指针,怎么能访问越界呢?

wishel 发表于 2008-11-28 18:28:36

m_mapTimer是什么类型?

rainfish 发表于 2008-11-28 23:18:29

回复 #2 wishel 的帖子

m_mapTime是map<long, void*> ,

rainfish 发表于 2008-11-28 23:21:28

而且把m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));
放在
CTimerTask<TYPE>* pTask = new CTimerTask<TYPE>( 0 );
      ACE_ASSERT( pTask );
      
      if ( pTask == NULL )
      {
            ACE_ERROR( (LM_ERROR,
                ACE_TEXT ("<CTimerManager::regist_period_cycle_task> new start CTimerTask failed!\n")) );
            
            return -1;
      }

      m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));//放在这里没有问题

         pTask->m_fnTask = pFun;
         pTask->m_sTime = ACE_Time_Value(startTime);
         pTask->m_interval = ACE_Time_Value(cycleSecond, cycleMillisecond);
      pTask->m_stData.data = data;
       //放在这里也没有问题
      //m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));
      // 注册任务
      pTask->m_lID = m_timer.schedule( pTask, (void*)&(pTask->m_stData),
            pTask->m_sTime, pTask->m_interval );
      
所以推断是m_timer.schedule的问题,可是一个指针,怎么会崩溃呢?

winston 发表于 2008-11-28 23:38:54

表现未必代表本质。我个人意见,可能跟线程同步有关,是线程同步导致。
因为没有更多代码,所以精确结论不好说。

rainfish 发表于 2008-11-29 11:20:32

回复 #5 winston 的帖子

线程同步的问题?m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));只是保存一个地址啊,就算线程同步,保存一个地址也能引起崩溃?请问原因是什么?请达人释疑,感激不尽

winston 发表于 2008-11-29 17:01:04

多追踪一下就可以了。这种问题很好调试。
你看看崩溃时候的数据是不是有问题。

newzai 发表于 2008-11-29 21:01:27

if ( pTask->m_lID <= 0 )
      {
            ACE_ERROR( (LM_ERROR,
                ACE_TEXT ("<CTimerManager::regist_single_task> schedule start time task failed(ID=%l)!\n"), pTask->m_lID) );

            delete pTask; # 在这里你把pTask给删除了。
            pTask = NULL;
            return 0;
      }
       m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask)); # 在这里你使用了pTask,难道不会有问题吗???不崩溃才怪

修改
    if ( pTask->m_lID <= 0 )
      {
            ACE_ERROR( (LM_ERROR,
                ACE_TEXT ("<CTimerManager::regist_single_task> schedule start time task failed(ID=%l)!\n"), pTask->m_lID) );

            delete pTask; # 在这里你把pTask给删除了。
            pTask = NULL;
            return 0;
       } else
            m_mapTimer.insert(pair<long, void*>(pTask->m_lID, (void*)pTask));

winston 发表于 2008-11-30 00:15:32

看起来还真是如此。

wishel 发表于 2008-11-30 01:50:20

原帖由 newzai 于 2008-11-29 21:01 发表 http://www.acejoy.com/bbs/images/common/back.gif
if ( pTask->m_lID m_lID) );

            delete pTask; # 在这里你把pTask给删除了。
            pTask = NULL;
            return 0;
      }
       m_mapTimer.insert(pair(pTask->m_lID, (void*)pTask)); ...

这个分支没走到,如果走到的话下面有个return0,不会往下走了
页: [1] 2
查看完整版本: 关于定时器崩溃的问题