ACE_Task问题.

allen_zhaozhencn 2005-09-07 05:56:58
有两个ACT_Task<ACE_MT_SYNCH>类派生的类TaskManager与Worker,分别对应实例对象A与B.
A对象创建了B.在a::svc中调用b.putq. 如果两个svc函数都不使用sleep,一切OK,当 前一个sleep值小于后者时,thr_mgr().wait()无法返回. 注:两个ACE_Task使用同一个ACE_Thread_Manager.

请问可能是什么原因? 谢谢...
...全文
209 10 打赏 收藏 举报
写回复
10 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lifengice0706 2005-09-12
几乎一整天都在看你的代码。先说两个解决方法吧!
1.TaskManager::ShutDown()中的m_bDone = true改为m_bDone = false。
2.TaskManager::ShutDown()中去掉msg_queue()->deactivate();这句。

我看到的现象是TaskManager::svc()没能成功退出。msg_queue()->deactivate()这句没必要。交给ace自己去作罢。

几点建议:
1.你想在两个task(或active-object)之间处理message-queue,可将ace_message_queue实例为ace_singleton,或使用ace_singleton单子你的其中一个task。
2.楼主的程序似乎是想一个task(TaskManager)完成putq(),多个task(worker)完成getq()。何不用一个task(worker)的activate()创建多个线程。


学艺不深,有错勿怪。
  • 打赏
  • 举报
回复
lifengice0706 2005-09-11
楼主能否帖的全点,特别是.h文件。我编译出好多undefined,因为是在单位帮你看,所以要快(被别人看到总不好的)。谢谢。
  • 打赏
  • 举报
回复
天一 2005-09-11
友情帮顶!
  • 打赏
  • 举报
回复
allen_zhaozhencn 2005-09-11

// worker.h

#include<ace/task.h>
#include<ace/synch.h>

class TaskManager;

class Worker : public ACE_Task<ACE_MT_SYNCH> //工作线程.
{
public:
Worker(TaskManager *pTaskManager, ACE_Thread_Manager *thr_mgr = 0);
virtual ~Worker();
protected:
int svc(void); //线程处理函数.

public:
int close(u_long flags = 0);

private:
TaskManager *m_pTaskManager;
};

// TaskManager.h


#include<ace/Task.h>
#include<ace/Synch.h>
#include<ace/thread_mutex.h>
#include<ace/guard_t.h>
#include<ace/message_block.h>

#include<queue>
#include<list>

class Worker;

class TaskManager : public ACE_Task<ACE_MT_SYNCH>
{
public:
TaskManager(ACE_UINT16 iMaxThread = DEFAULT_MAX_THREAD, ACE_Thread_Manager *pThreadManager = 0);
virtual ~TaskManager();

public:
void ShutDown( ); //关闭任务.

protected:
int svc(void);

inline bool IsDone( ) const
{
return m_bDone;
}

private:
enum {DEFAULT_MAX_THREAD = 10};

private:
virtual bool CreateThreadPool( ); //建立线程池
virtual Worker* ChooseThread( ); //从"线程池"列表中取出第一个线程.
virtual void ReleaseThread(Worker *pWorker); //Worker线程处理完"特定任务"后,执行该函数,将pWorker重新"入线程池列表".

private:
bool m_bAlive; //活动标志,指示当前任务是否正在运行.
bool m_bDone; //结束完成标志
ACE_UINT16 m_iMaxThread; //线程池的最大线程个数.

ACE_Thread_Mutex m_QueueMutex;
ACE_Condition<ACE_Thread_Mutex> m_Condition;

typedef std::queue<Worker*> WORKER_QUEUE;
WORKER_QUEUE m_WorkerQueue; //线程队列.

typedef std::list<Worker*> WORKER_LIST; //用于保存所有的"线程对象指针".
WORKER_LIST m_WorkerList;

friend class Worker;
};


谢 谢 。
  • 打赏
  • 举报
回复
rocandroc 2005-09-09
up
  • 打赏
  • 举报
回复
saliors 2005-09-08
看不明白,建议贴代码
  • 打赏
  • 举报
回复
allen_zhaozhencn 2005-09-08
贴了两次,两次一样的。
  • 打赏
  • 举报
回复
allen_zhaozhencn 2005-09-08
////////////////////////////////////////////////////////////////////////
// TaskManager class implement
///////////////////////////////////////////////////////////////////////


TaskManager::TaskManager(ACE_UINT16 iMaxThread, ACE_Thread_Manager *pThreadManager) : ACE_Task<ACE_MT_SYNCH>(pThreadManager), m_bAlive(false), m_bDone(false), m_iMaxThread(iMaxThread), m_QueueMutex(), m_Condition(m_QueueMutex)
{

}

TaskManager::~TaskManager()
{
if (m_bAlive)
{
ShutDown( );
}
}


void TaskManager::ShutDown()
{

ACE_DEBUG ( (LM_DEBUG, "TaskManager::ShutDown is called\n") );
ACE_DEBUG ( (LM_DEBUG, "TaskManager::ShutDown wait all thread exit \n") );


m_bDone = true;
msg_queue()->deactivate(); //通知结束TaskManager线程.
wait( ); //等待本线程结束.

WORKER_LIST::iterator iterBegin = m_WorkerList.begin();
WORKER_LIST::iterator iterEnd = m_WorkerList.end();

for (; iterBegin!=iterEnd; ++iterBegin)
{
delete (*iterBegin); //释放所有Worker线程对象.
}


m_bAlive = false;

}


bool TaskManager::CreateThreadPool( )
{
ACE_DEBUG( (LM_DEBUG, "TaskManager::CreateThreadPool is called\n") );

ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex, 1);

Worker *pWorker = NULL;

for (int i=0; i<m_iMaxThread; ++i)
{
pWorker = new(std::nothrow) Worker( this, thr_mgr() ); //注意: Worker线程使用与TaskManager相同的ACE_Thread_Manager.!!!

if (pWorker != NULL)
{
m_WorkerList.push_back(pWorker);
}
else
{
break;
}
}

WORKER_LIST::iterator iterBegin = m_WorkerList.begin();
WORKER_LIST::iterator iterEnd = m_WorkerList.end();

if (i>=m_iMaxThread)
{
for (; iterBegin!=iterEnd; ++iterBegin)
{
m_WorkerQueue.push(*iterBegin); //将Worker线程入队列.
(*iterBegin)->activate( );
}
}
else
{
for (; iterBegin!=iterEnd; ++iterBegin)
{
delete (*iterBegin);
}
}

if ( i>=m_iMaxThread )
{
m_bAlive = true;
return true;
}
else
{
m_bAlive = false;
return false;
}

}



Worker* TaskManager::ChooseThread( )
{
ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex);

ACE_DEBUG( (LM_DEBUG, "TaskManager::ChooseThread is called\n") );

while ( m_WorkerQueue.empty() ) //等待线程池列表中有线程可用.
{
ACE_DEBUG( (LM_DEBUG, "m_Condition.wait is called\n") );
m_Condition.wait( );
}

Worker *pWorker = NULL;
pWorker = m_WorkerQueue.front( );
m_WorkerQueue.pop( );

return pWorker;
}


void TaskManager::ReleaseThread(Worker *pWorker)
{
ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex);

ACE_DEBUG( (LM_DEBUG, "TaskManager::ReleaseThread is called\n") );

m_WorkerQueue.push(pWorker);

m_Condition.signal( );

}


int TaskManager::svc( )
{
bool bResult = false;
Worker *pWorker = NULL;
ACE_Message_Block *pMB = NULL;

ACE_DEBUG( (LM_DEBUG, "TaskManager::svc is called\n") );

bResult = CreateThreadPool( );

if (!bResult)
{
return -1;
}

for (; !IsDone(); )
{
if ( getq(pMB, NULL) == -1)
{
break;
}

pWorker = ChooseThread( );

if ( pWorker!=NULL && pWorker->putq(pMB, NULL) == -1)
{
break;
}

// ACE_OS::sleep( ACE_Time_Value(0, 100) );
//!!!! 位置:A  
    //

}

return 0;
}

////////////////////////////////////////////////////////////////////////
// Worker class implement
///////////////////////////////////////////////////////////////////////

Worker::Worker(TaskManager *pTaskManager, ACE_Thread_Manager *thr_mgr /* = 0 */) : ACE_Task<ACE_MT_SYNCH>(thr_mgr, 0)
{
m_pTaskManager = pTaskManager;
}

Worker::~Worker()
{
msg_queue()->deactivate();

if (thr_mgr() !=0)
{
wait( ); //等待Task中所有线程结束.
}

}


int Worker::svc( )
{
ACE_Message_Block *pMB = NULL;

for (; !m_pTaskManager->IsDone(); )
{
if ( getq(pMB, NULL) == -1)
{
break;
}

ACE_OS::printf("Thread ID: %d, %s\n", ACE_Thread::self(), std::string(pMB->base(), pMB->length() ).c_str() );

pMB->release();

m_pTaskManager->ReleaseThread(this);

// ACE_OS::sleep( 1 ); //位置B
// 位置A与位置B 都去掉 ACE_OS::sleep ,一切OK. 或使用相同的时间值.也OK.
// 如果B处的时间值>A处时间值, TaskManager对象内的线程无法返回,挂死。 ???


}

return 0;

}


int Worker::close(u_long flags /* = 0 */)
{
ACE_DEBUG ( (LM_DEBUG, "Thread ID: %d Worker::close is called\n", ACE_Thread::self() ) );

return ACE_Task<ACE_MT_SYNCH>::close( );
}


///////////////////////////////////////////////////////////////////////////////


int main(int argc, char* argv[])
{
int iThread = 0;

std::cout << "输入线程个数" << std::endl;

std::cin >> iThread;

ACE_Thread_Manager ATM;
TaskManager TM(iThread,&ATM);
ACE_Message_Block *pMB = NULL;

TM.activate();

for (int i =1; i<100; ++i)
{
pMB = new ACE_Message_Block("abc", 3);
pMB->wr_ptr( pMB->wr_ptr() + 3 );

TM.putq( pMB );
}


ACE_OS::sleep( ACE_Time_Value(5,0) );


TM.ShutDown( );



return 0;
}


  • 打赏
  • 举报
回复
allen_zhaozhencn 2005-09-08
////////////////////////////////////////////////////////////////////////
// TaskManager class implement
///////////////////////////////////////////////////////////////////////


TaskManager::TaskManager(ACE_UINT16 iMaxThread, ACE_Thread_Manager *pThreadManager) : ACE_Task<ACE_MT_SYNCH>(pThreadManager), m_bAlive(false), m_bDone(false), m_iMaxThread(iMaxThread), m_QueueMutex(), m_Condition(m_QueueMutex)
{

}

TaskManager::~TaskManager()
{
if (m_bAlive)
{
ShutDown( );
}
}


void TaskManager::ShutDown()
{

ACE_DEBUG ( (LM_DEBUG, "TaskManager::ShutDown is called\n") );
ACE_DEBUG ( (LM_DEBUG, "TaskManager::ShutDown wait all thread exit \n") );


m_bDone = true;
msg_queue()->deactivate(); //通知结束TaskManager线程.
wait( ); //等待本线程结束.

WORKER_LIST::iterator iterBegin = m_WorkerList.begin();
WORKER_LIST::iterator iterEnd = m_WorkerList.end();

for (; iterBegin!=iterEnd; ++iterBegin)
{
delete (*iterBegin); //释放所有Worker线程对象.
}


m_bAlive = false;

}


bool TaskManager::CreateThreadPool( )
{
ACE_DEBUG( (LM_DEBUG, "TaskManager::CreateThreadPool is called\n") );

ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex, 1);

Worker *pWorker = NULL;

for (int i=0; i<m_iMaxThread; ++i)
{
pWorker = new(std::nothrow) Worker( this, thr_mgr() ); //注意: Worker线程使用与TaskManager相同的ACE_Thread_Manager.!!!

if (pWorker != NULL)
{
m_WorkerList.push_back(pWorker);
}
else
{
break;
}
}

WORKER_LIST::iterator iterBegin = m_WorkerList.begin();
WORKER_LIST::iterator iterEnd = m_WorkerList.end();

if (i>=m_iMaxThread)
{
for (; iterBegin!=iterEnd; ++iterBegin)
{
m_WorkerQueue.push(*iterBegin); //将Worker线程入队列.
(*iterBegin)->activate( );
}
}
else
{
for (; iterBegin!=iterEnd; ++iterBegin)
{
delete (*iterBegin);
}
}

if ( i>=m_iMaxThread )
{
m_bAlive = true;
return true;
}
else
{
m_bAlive = false;
return false;
}

}



Worker* TaskManager::ChooseThread( )
{
ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex);

ACE_DEBUG( (LM_DEBUG, "TaskManager::ChooseThread is called\n") );

while ( m_WorkerQueue.empty() ) //等待线程池列表中有线程可用.
{
ACE_DEBUG( (LM_DEBUG, "m_Condition.wait is called\n") );
m_Condition.wait( );
}

Worker *pWorker = NULL;
pWorker = m_WorkerQueue.front( );
m_WorkerQueue.pop( );

return pWorker;
}


void TaskManager::ReleaseThread(Worker *pWorker)
{
ACE_Guard<ACE_Thread_Mutex> guard(m_QueueMutex);

ACE_DEBUG( (LM_DEBUG, "TaskManager::ReleaseThread is called\n") );

m_WorkerQueue.push(pWorker);

m_Condition.signal( );

}


int TaskManager::svc( )
{
bool bResult = false;
Worker *pWorker = NULL;
ACE_Message_Block *pMB = NULL;

ACE_DEBUG( (LM_DEBUG, "TaskManager::svc is called\n") );

bResult = CreateThreadPool( );

if (!bResult)
{
return -1;
}

for (; !IsDone(); )
{
if ( getq(pMB, NULL) == -1)
{
break;
}

pWorker = ChooseThread( );

if ( pWorker!=NULL && pWorker->putq(pMB, NULL) == -1)
{
break;
}

// ACE_OS::sleep( ACE_Time_Value(0, 100) );
//!!!! 位置:A  
    //

}

return 0;
}

////////////////////////////////////////////////////////////////////////
// Worker class implement
///////////////////////////////////////////////////////////////////////

Worker::Worker(TaskManager *pTaskManager, ACE_Thread_Manager *thr_mgr /* = 0 */) : ACE_Task<ACE_MT_SYNCH>(thr_mgr, 0)
{
m_pTaskManager = pTaskManager;
}

Worker::~Worker()
{
msg_queue()->deactivate();

if (thr_mgr() !=0)
{
wait( ); //等待Task中所有线程结束.
}

}


int Worker::svc( )
{
ACE_Message_Block *pMB = NULL;

for (; !m_pTaskManager->IsDone(); )
{
if ( getq(pMB, NULL) == -1)
{
break;
}

ACE_OS::printf("Thread ID: %d, %s\n", ACE_Thread::self(), std::string(pMB->base(), pMB->length() ).c_str() );

pMB->release();

m_pTaskManager->ReleaseThread(this);

// ACE_OS::sleep( 1 ); //位置B
// 位置A与位置B 都去掉 ACE_OS::sleep ,一切OK. 或使用相同的时间值.也OK.
// 如果B处的时间值>A处时间值, TaskManager对象内的线程无法返回,挂死。 ???


}

return 0;

}


int Worker::close(u_long flags /* = 0 */)
{
ACE_DEBUG ( (LM_DEBUG, "Thread ID: %d Worker::close is called\n", ACE_Thread::self() ) );

return ACE_Task<ACE_MT_SYNCH>::close( );
}


///////////////////////////////////////////////////////////////////////////////


int main(int argc, char* argv[])
{
int iThread = 0;

std::cout << "输入线程个数" << std::endl;

std::cin >> iThread;

ACE_Thread_Manager ATM;
TaskManager TM(iThread,&ATM);
ACE_Message_Block *pMB = NULL;

TM.activate();

for (int i =1; i<100; ++i)
{
pMB = new ACE_Message_Block("abc", 3);
pMB->wr_ptr( pMB->wr_ptr() + 3 );

TM.putq( pMB );
}


ACE_OS::sleep( ACE_Time_Value(5,0) );


TM.ShutDown( );



return 0;
}


  • 打赏
  • 举报
回复
lifengice0706 2005-09-07
楼主的Sleep()在何处?你的意思是a.svc()和b.svc()中都有吗?最好有简单的代码!!
  • 打赏
  • 举报
回复
相关推荐
发帖
网络编程
加入

1.8w+

社区成员

VC/MFC 网络编程
社区管理员
  • 网络编程
申请成为版主
帖子事件
创建了帖子
2005-09-07 05:56
社区公告
暂无公告