| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 297 人关注过本帖
标题:关于ACE到问题
取消只看楼主 加入收藏
truetempus
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2012-8-7
收藏
 问题点数:0 回复次数:0 
关于ACE到问题
我目前是在linux下用ACE开发一个关于TCP的通道模块,运用了ACE_Reactor的Accetpor-Connector框架,其中实现了一个服务处理器,ChannelSvcHandler,现将我到代码贴下
class ChannelSvcHandler : public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH> {
  typedef ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH> PARENT;
public:
  ChannelSvcHandler();
  virtual ~ChannelSvcHandler();
public:
  //打开服务处理器
  virtual int open (void *p);
  //接收处理函数
  virtual int handle_input (ACE_HANDLE fd);
  //数据发送线程
  virtual int svc();
  //退出线程并关闭连接
  int QuitSvcAndClose(bool bupdate = true);
private:
  //通道连接器指针
  ChannelConnector * pConnector_;
};
int ChannelSvcHandler:pen(void *p) {
  //调用父类函数,完成向反应器注册
  PARENT:pen();
  //保存通道连接器指针
  if (0 != p) {
  pConnector_ = reinterpret_cast<ChannelConnector *>(p);
  }
  //激活数据发送线程
  this->activate();
  return 0;
}
int ChannelSvcHandler::handle_input(ACE_HANDLE fd) {
  //创建接收缓存
  ACE_Message_Block *mbk = 0;
  ACE_NEW_RETURN(mbk,ACE_Message_Block(DEFAULT_BLOCK_SIZE),0);
  //接收数据
  ssize_t count = this->peer().recv(mbk->wr_ptr(),mbk->size());
  if (count > 0) {
  //接收成功,移动写指针
  mbk->wr_ptr(count);
  //返回接收数据
  if (!pConnector_->utReceiveMessage(mbk)) {
  mbk->release();
  ACE_ERROR((LM_ERROR,ACE_TEXT("接收数据返回失败!\n")));
  }
  } else {
  //接收失败,表示对端关闭或网络异常
  mbk->release();
  ACE_DEBUG((LM_DEBUG,ACE_TEXT("连接异常,将断开与对端到连接!\n")));
  //退出线程并关闭连接
  QuitSvcAndClose();
  }
  return 0;
}
int ChannelSvcHandler::svc() {
  ACE_Message_Block *mbk;
  while (1) {
  //从队列获取数据
  if (-1 != this->getq(mbk)) {
  //判断是否为退出消息
  if (mbk->size() == 0 && mbk->msg_type() == ACE_Message_Block::MB_STOP) {
  //是则跳出循环,退出线程,关闭连接
  mbk->release();
  msg_queue()->close();
  ACE_DEBUG((LM_DEBUG,ACE_TEXT("收到退出消息,数据发送线程退出,并断开连接!\n")));
  break;
  } else {
  //否则为需发送到数据
  while (mbk->length() > 0) {
  //发送数据到对端
  ssize_t count = this->peer().send(mbk->rd_ptr(),mbk->length());
  if (count > 0) {
  //发送成功,移动读指针
  mbk->rd_ptr(count);
  } else {
  //发送失败,表示网络异常,直接跳出,等待接收处理函数处理
  break;
  }
  }
  //发送完毕后释放资源
  mbk->release();
  }
  }
  }
  return 0;
}
int ChannelSvcHandler:uitSvcAndClose(bool bupdate) {
  //判断是否需要更新通道连接器中到服务处理器指针
  if (bupdate) {
  pConnector_->UpdateSvcHandler();
  }
  //构造退出消息
  ACE_Message_Block *quit_msg = 0;
  ACE_NEW_RETURN(quit_msg,ACE_Message_Block(0,ACE_Message_Block::MB_STOP),0);
  //放入队列头
  if (-1 == this->ungetq(quit_msg)) {
  ACE_ERROR_RETURN((LM_ERROR,ACE_TEXT("退出消息压入队列失败!\n")),0);
  }
  //等待数据发送线程退出
  this->wait();
  return 1;
}
现 在将问题具体说说,如果因为某种原因或主动关闭程序,从程序主线程中调用QuitSvcAndClose,该服务处理器可正常关闭;如果所对端关闭或网络 异常等原因,导致handle_input中接收到的数据为0,这时我也会调用QuitSvcAndClose来先关闭线程,进而关闭服务处理器,但这时 候QuitSvcAndClose中到this->wait就一直不返回阻塞在那,svc线程中的 ACE_DEBUG((LM_DEBUG,ACE_TEXT("收到退出消息,数据发送线程退出,并断开连接!\n")))这条日志已经打印,表示线程已 退出,为什么会不返回呢,不知道我在handle_input中调用这样到这样到退出线程到函数再等待线程退出是否合适????
后来我想直接把 open函数中的activate参数设成THR_DETACHED,然后QuitSvcAndClose中不掉用wait直接返回,程序没有阻塞正常运 行了,但通过打印到信息可以看出,hande_input函数貌似被调用了N次,这是我最搞不懂到地方!!!至于开启到线程到底是该设成 THR_DETACHED还算THR_JOINABLE,两者到区别除了一个所系统自动回收资源,另一个是需要wait才能回收外,还有啥区别,我们该如 何选择呢???
2012-08-07 09:58
快速回复:关于ACE到问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035248 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved