找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6644|回复: 2

在Proactor模式中,线程池退出时为什么程序崩溃?

[复制链接]
发表于 2008-5-11 17:20:14 | 显示全部楼层 |阅读模式
程序采用MFC+ACE,代码如下:
头文件
以下内容为程序代码:

class Asynch_Thread_Pool : protected ACE_Task_Base
{
public:
  typedef enum { DEFAULT = 0, AIOCB, SIG, SUN, CB } ProactorType;
  Asynch_Thread_Pool();
  virtual ~Asynch_Thread_Pool();
  static Asynch_Thread_Pool * instance ();
  ACE_INT32 start (ACE_UINT32 num_threads = 5, ACE_Byte cpu_num = 0,
   ProactorType type_proactor = DEFAULT, ACE_UINT32 max_op = 0);
  void stop();
protected:
  virtual ACE_INT32 svc();
  ACE_INT32 create_proactor (ACE_Byte cpu_num, ProactorType type_proactor, ACE_UINT32 max_op);
  ACE_INT32 delete_proactor ();
private:
  ACE_SYNCH_RECURSIVE_MUTEX lock_;
  ACE_SYNCH_SEMAPHORE sem_;
  ACE_Proactor * proactor_;
};



实现文件:
以下内容为程序代码:

Asynch_Thread_Pool::Asynch_Thread_Pool() :
lock_ (),
sem_ ((ACE_UINT32) 0),
proactor_(0)
{
ACE_TRACE("Asynch_Thread_Pool::Asynch_Thread_Pool\n");
}
Asynch_Thread_Pool::~Asynch_Thread_Pool()
{
ACE_TRACE("Asynch_Thread_Pool::~Asynch_Thread_Pool\n");
}
Asynch_Thread_Pool *
Asynch_Thread_Pool::instance ()
{
ACE_TRACE ("Asynch_Thread_Pool::instance\n");
return ACE_Singleton<Asynch_Thread_Pool,
  ACE_SYNCH_NULL_MUTEX>::instance ();
}
ACE_INT32
Asynch_Thread_Pool::create_proactor (ACE_Byte cpu_num,
          ProactorType type_proactor,
          ACE_UINT32 max_op)
{
ACE_TRACE("Asynch_Thread_Pool::create_proactor\n");
ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
  monitor,
  this->lock_,
  -1);
#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
ACE_UNUSED_ARG (type_proactor);
ACE_UNUSED_ARG (max_op);
ACE_WIN32_Proactor *proactor_impl = 0;
ACE_NEW_RETURN (proactor_impl,
  ACE_WIN32_Proactor(cpu_num * 2),
  -1);
//ACE_TRACE("Create Proactor Type = WIN32\n");
#elif defined (ACE_HAS_AIO_CALLS)
ACE_POSIX_Proactor * proactor_impl = 0;
switch (type_proactor)
{
case AIOCB:
  ACE_NEW_RETURN (proactor_impl,
   ACE_POSIX_AIOCB_Proactor (max_op),
   -1);
  ACE_TRACE("Create Proactor Type = AIOCB\n");
  break;
#if defined(ACE_HAS_POSIX_REALTIME_SIGNALS)
case SIG:
  ACE_NEW_RETURN (proactor_impl,
   ACE_POSIX_SIG_Proactor (max_op),
   -1);
  ACE_TRACE("Create Proactor Type = SIG\n");
  break;
#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */
#  if defined (sun)
case SUN:
  ACE_NEW_RETURN (proactor_impl,
   ACE_SUN_Proactor (max_op),
   -1);
  ACE_TRACE("Create Proactor Type = SUN\n");
  break;
#  endif /* sun */
#  if defined (__sgi)
case CB:
  ACE_NEW_RETURN (proactor_impl,
   ACE_POSIX_CB_Proactor (max_op),
   -1);
  ACE_TRACE("Create Proactor Type = CB\n");
  break;
#  endif
default:
  ACE_TRACE("Create Proactor Type = DEFAULT\n");
  break;
}
#endif // (ACE_WIN32) && !defined (ACE_HAS_WINCE)
ACE_ASSERT(proactor_impl);
ACE_NEW_RETURN (this->proactor_,
  ACE_Proactor (proactor_impl, 1 ),
  -1);
ACE_Proactor::instance (this->proactor_, 1);
return 0;
}
ACE_INT32
Asynch_Thread_Pool::delete_proactor()
{
ACE_TRACE("Asynch_Thread_Pool::delete_proactor\n");
ACE_ASSERT(this->proactor_ != 0);
ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
  monitor,
  this->lock_,
  -1);
//ACE_TRACE("Delete Proactor\n");
// 这行要不要都无所为,因为在VC7中没有内存问题,
// 但在VC6中加入该行后会产生内存问题,不知是不是boundschecker不准确
//ACE_Proactor::close_singleton ();
this->proactor_ = 0;
return 0;
}
ACE_INT32
Asynch_Thread_Pool::start (ACE_UINT32 num_threads,
         ACE_Byte cpu_num,
         ProactorType type_proactor,
         ACE_UINT32 max_op)
{
ACE_TRACE("Asynch_Thread_Pool::start\n");
ACE_ASSERT (this->proactor_ == 0 && num_threads > 0 &&
  type_proactor >= DEFAULT && type_proactor <= CB);
if (this->proactor_) return -1;
if (this->create_proactor (cpu_num, type_proactor, max_op) == -1)
  ACE_ERROR_RETURN ((LM_ERROR,
  ACE_TEXT ("%p.\n"),
  ACE_TEXT ("unable to create proactor")),
  -1);
if (this->activate (THR_NEW_LWP | THR_JOINABLE, num_threads) == -1)
  ACE_ERROR_RETURN ((LM_ERROR,
  ACE_TEXT ("%p.\n"),
  ACE_TEXT ("unable to activate thread pool")),
  -1);
for (; num_threads > 0; num_threads--)
{
  this->sem_.acquire ();
}
return 0;
}
void
Asynch_Thread_Pool::stop ()
{
ACE_TRACE("Asynch_Thread_Pool::stop\n");
if (!this->proactor_) return ;
//ACE_TRACE("Calling End Proactor event loop\n");
ACE_Proactor::end_event_loop ();
if (this->wait () == -1)
  ACE_ERROR ((LM_ERROR,
  ACE_TEXT ("%p.\n"),
  ACE_TEXT ("unable to stop thread pool")));
this->delete_proactor();
}
ACE_INT32
Asynch_Thread_Pool::svc()
{
ACE_TRACE (ACE_TEXT ("Task started\n"));
this->sem_.release (1);
ACE_Proactor::run_event_loop ();
//ACE_TRACE(ACE_TEXT ("Task finished\n"));
return 0;
}



在Dialog关闭时OnClose中调用stop,崩溃。。。。不知道为什么会崩
 楼主| 发表于 2008-5-11 17:20:26 | 显示全部楼层
崩在stop函数中的 ACE_Proactor::end_event_loop ();这行
 楼主| 发表于 2008-5-11 17:20:43 | 显示全部楼层
Proactor中,产生崩溃,大都是因为你的对象清除了,可是线程还在继续运行,继续使用被清除的对象。你应该先确保让线程退出,再清除对象。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-21 21:03 , Processed in 0.025420 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表