peakzhang 发表于 2008-5-11 17:20:14

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

程序采用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,崩溃。。。。不知道为什么会崩

peakzhang 发表于 2008-5-11 17:20:26

崩在stop函数中的 ACE_Proactor::end_event_loop ();这行

peakzhang 发表于 2008-5-11 17:20:43

Proactor中,产生崩溃,大都是因为你的对象清除了,可是线程还在继续运行,继续使用被清除的对象。你应该先确保让线程退出,再清除对象。
页: [1]
查看完整版本: 在Proactor模式中,线程池退出时为什么程序崩溃?