您当前的位置: 首页 > 

phymat.nico

暂无认证

  • 0浏览

    0关注

    1967博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ACE入门---很好的文章

phymat.nico 发布时间:2017-12-20 21:52:13 ,浏览量:0

转自:http://www.cnblogs.com/dubingsky/archive/2009/07/22/1528292.html

ACE编译

1. 设置环境变量

  1. 在操作系统添加一个名为ACE_ROOT的用户环境变量,值为刚才ace的解压路径D:\Develop\ACE_wrappers。
  2. 添加用户的Path环境变量,值为%ACE_ROOT%\lib,这样才能保证系统能找到ace生成的动态连接库。
  3. 设置VS2005的C++开发项目信息,依次打开菜单 工具-选项-项目和解决方案-VC++目录 ,在右侧目录列表中选择"包含目录",添加$(ACE_ROOT),在右侧目录列表中选择"库文件",添加$(ACE_ROOT)\lib。

2. 在 ACE_wrappers\ace目录下创建 config.h 文件,写入: #include "ace/config-win32.h" 

Code 3. 如果你希望使用标准的 C++ 头文件(例如 iostream、cstdio 等)在 #include "ace/config-win32.h" 前加入:  #define ACE_HAS_STANDARD_CPP_LIBRARY 1  4. 如果你希望使用 MFC 库,那么 config.h 中加入:  #define ACE_HAS_MFC 1  如果你希望使用 MFC 静态库,那么加入:  #define ACE_USES_STATIC_MFC  5. 如果你希望编译静态版本的 ACE 库,那么在 config.h 中加入:  #define ACE_AS_STATIC_LIBS  6. 如果你希望减少静态库的大小,可以禁止使用 inline,在 config.h 的 #include "ace/config-win32.h" 前加入:  #define ACE_NO_INLINE 

 

ACE结构简介

1)ACE OS adaptation层:封装了 OS API,对上层提供 OS平台无关的接口。

2)C++ wrapper facades层:位于 OS adaptation之上,提供了与之相似的功能,这些功能使用 C++的类封装起来,而不是 C 语言 API。每个 wrapper facade都包含一个或者一个以上的类。我们可以有选择的继承、聚合这些 wrapper facade。

3)框架层(Framework layer)

框架层在 C++ wrapper facades层之上,它集成和扩充了 wrapper facade类。

事件多路分离和分发框架

ACE Reactor 和 ACE Proactor 实现了 Reactor 模式和 Proactor模式。

连接建立和服务初始化框架

ACE Acceptor-Connector框架实现了 Acceptor-Connector模式。

并发框架

ACE 提供了 Task框架实现了并发模式。

服务配置框架

ACE 的服务配置框架实现了 Component Configurator模式。

流框架

ACE 的流框架实现了 Pipes and Fiters模式。

4)ACE网络组件层

组件(component)就是软件系统中被封装的一个部分,ACE发行包中的组件用于提供以下功能:

演示 ACE

提供常见网络服务的可复用实现。如提供日志记录、时间同步等服务的可复用实现。

 

线程的创建与管理

一.线程入口函数

所有线程必须从一个指定的函数开始执行,该函数称为线程函数,它必须具有下列原型: void* worker(void *arg) {} 该函数输入一个void *型的参数,可以在创建线程时传入。 注意:所有的线程启动函数(方法)必须是静态的或全局的(就如同直接使用OS线程API时所要求的一样)。

二.线程基本操作

1.创建一个线程

一个进程的主线程是由操作系统自动生成,如果你要让一个主线程创建额外的线程,可以通过ACE_Thread::spawn()实现,该函数一般的使用方式如下:

ACE_thread_t threadId;

ACE_hthread_t threadHandle;

ACE_Thread::spawn(

    (ACE_THR_FUNC)worker,       //线程执行函数

    NULL,                       //执行函数参数

    THR_JOINABLE | THR_NEW_LWP,

    &threadId,

    &threadHandle

    );

ACE_Thread::spawn((ACE_THR_FUNC)worker)使用其默认参数,来创建一个worker的线程。

ACE_Thread::spawn_n函数来创建多个线程。

2.终止线程

在线程函数体中ACE_Thread::exit()调用即可终止线程执行。

3.设定线程的相对优先级

当一个线程被首次创建时,它的优先级等同于它所属进程的优先级。一个线程的优先级是相对于其所属的进程的优先级而言的。可以通过调用ACE_Thread::setprio函数改变线程的相对优先级,该函数的调用方式如下: ACE_Thread::setprio(threadHandle,ACE_DEFAULT_THREAD_PRIORITY)

4.挂起及恢复线程

挂起线程可以通过来实现,它能暂停一个线程的执行,其调用方式如下ACE_Thread::suspend(threadHandle)。 相应的,可以通过ACE_Thread::resume(threadHandle)恢复被挂起的线程的执行。

5.等待线程结束

在主函数中调用ACE_Thread::join(threadHandle)可阻塞主函数,直道线程结束才能继续执行。

6.停止线程

在主函数中调用ACE_Thread::cancel (threadHandle)可停止线程的执行(在Unix底下可以,而在windows下好像不起作用,有待检验)。

三.程序示例

下面例子演示了如何用ace创建一个线程。

#include "ace/Thread.h"

#include "ace/Synch.h"

 

#pragma comment(lib,"ACEd.lib")

 

 

#include

usingnamespace std;

void* worker(void *arg)

{

for(int i=0;ideactivate();    ++loop;   }   if(loop == 2)   {    ACE_OS::sleep(2);    //将消息队列的状态设置成ACTIVATED    //消息又可以使用了    mq->activate();    ++loop;   }   if(loop == 3)   {    ACE_OS::sleep(10);    //消费两个消息之后,数据量就小于5了,低于低水位将唤醒生产者    ACE_Message_Block *mb;    mq->dequeue_head (mb);    mq->dequeue_head (mb);    ACE_DEBUG((LM_DEBUG, "(%P : %t) consumer wake up producer!!\n"));    ++loop;   }     }     return NULL; } int main(int argc,char* argv[]) {  mq = ACE_Message_Queue_Factory::create_static_message_queue();  int priority;  //使用随机数作为消息的优先级  //数字越高,优先级越高  priority = ACE_OS::rand() % 100;  mb1 = new ACE_Message_Block(S1,sizeof S1, priority);  priority = ACE_OS::rand() % 100;  mb2 = new ACE_Message_Block(S2,sizeof S2, priority);  priority = ACE_OS::rand() % 100;  mb3 = new ACE_Message_Block(S3,sizeof S3, priority);  priority = ACE_OS::rand() % 100;  mb4 = new ACE_Message_Block(S4,sizeof S4, priority);  //将消息压入队列中,enqueue_prio根据消息的优先级将消息放到适当的位置上  //enqueue_head只是简单地将数据存入队列中,而不考虑消息的优先级  //使用enqueue_prio压入消息后,可以简单通过dequeue_head和dequeue_tail  //分别按优先级从高到低和从低到高取消息  //如果使用enqueue_head和enqueue_tail压入消息  //则需要通过dequeue_prio来按照消息的优先级依次将消息出队列  //没有必要既使用enqueue_prio压入消息,又实用dequeue_prio来取消息  mq->enqueue_prio (mb1);  mq->enqueue_prio (mb2);  mq->enqueue_prio (mb3);  mq->enqueue_prio (mb4);  //输出静态消息队列的相关信息  //高低水位默认值均为16384  ACE_DEBUG((LM_DEBUG, "count : %d, bytes : %d, length : %d, high_water_mark : %d, low_water_mark : %d, status : %d\n",   mq->message_count(), mq->message_bytes(), mq->message_length(),   mq->high_water_mark(), mq->low_water_mark(),   mq->state()));  ACE_Message_Block *mb;  //使用next遍历消息,遍历的顺序为高优先级到底优先级  ACE_DEBUG((LM_DEBUG, "===========next=============\n"));  //peek一下,并不弹出消息,类似Windows的PeekMessage  mq->peek_dequeue_head(mb);  do  {   ACE_DEBUG((LM_DEBUG, "message: %s, priority: %d\n", mb->rd_ptr(), mb->msg_priority()));  }while(mb = mb->next());  //使用迭代器遍历消息队列,遍历的顺序为高优先级到底优先级  ACE_DEBUG((LM_DEBUG, "=========iterator=============\n"));  ACE_Message_Queue::ITERATOR iterator (*mq);     for (ACE_Message_Block *entry = 0;          iterator.next (entry) != 0;          iterator.advance ())  {   ACE_DEBUG((LM_DEBUG, "message: %s, priority: %d\n", entry->rd_ptr(), entry->msg_priority()));  }  ACE_DEBUG((LM_DEBUG, "============dequeue_head==========\n"));  while(mq->dequeue_head (mb) != -1)  {   ACE_DEBUG((LM_DEBUG, "message: %s, priority: %d\n", mb->rd_ptr(), mb->msg_priority()));   //这里如果不判断的话,消息队列空时会导致主线程被阻塞   if(mq->is_empty())    break;  }  ACE_DEBUG((LM_DEBUG, "\n\n"));  //测试高低水位和队列的state使用,进行测试之前mq队列已空///  //产生一个生产者线程  ACE_Thread_Manager::instance()->spawn_n          (           1,           (ACE_THR_FUNC) produce     );  产生两个消费者线程  ACE_Thread_Manager::instance()->spawn_n          (           1,           (ACE_THR_FUNC) consume     );  //挂起主线程  ACE_Thread_Manager::instance()->wait();    return 0; }

 

 

 

ACE中TCP通信

Tcp通信过程一般为如下步骤:

1.        服务器绑定端口,等待客户端连接。

2.        客户端通过服务器的ip和服务器绑定的端口连接服务器。

3.        服务器和客户端通过网络建立一条数据通路,通过这条数据通路进行数据交互。

常用API:

1. ACE_INET_Addr类。

ACE"地址"类ACE_Addr的子类,表示TCP/IP和UDP/IP的地址。它通常包含机器的ip和端口信息,通过它可以定位到所通信的进程。

定义方式: ACE_INET_Addr addInfo(3000,"192.168.1.100"); 常用方法:

1.        get_host_name    获取主机名

2.        get_ip_address    获取ip地址

3.        get_port_number    获取端口号

2. ACE_SOCK_Acceptor类。

服务期端使用,用于绑定端口和被动地接受连接。 常用方法:

1.        open 绑定端口

2.        accept建立和客户段的连接

3.ACE_SOCK_Connector类。

客户端使用,用于主动的建立和服务器的连接。 常用方法:

1.        connect()    建立和服务期的连接。

4. ACE_SOCK_Stream类。

客户端和服务器都使用,表示客户段和服务器之间的数据通路。 常用方法:

1.        send ()    发送数据

2.        recv ()    接收数据

3.        close()    关闭连接(实际上就是断开了socket连接)。

代码示例:

下面例子演示了如何如何用ACE创建TCP通信的Server端。

#include "ace/SOCK_Acceptor.h"

#include "ace/SOCK_Stream.h"

#include "ace/INET_Addr.h"

#include "ace/OS.h"

 

#include

#include

usingnamespace std;

 

int main(int argc,char *argv[])

{

    ACE_INET_Addr port_to_listen(3000);       //绑定的端口

    ACE_SOCK_Acceptor acceptor;

    if (acceptor.open (port_to_listen, 1) == -1)    //绑定端口

    {

        cout

关注
打赏
1659628745
查看更多评论
立即登录/注册

微信扫码登录

0.0520s