使用 ACE 库框架在 UNIX 中开发高性能并发应用

ACE在研究gem secs的一个开源库的时候,发现一个很强大的ACE开源库,记录下做些介绍 ACE是一个开源的C++框架,用于开发高性能的分布式实时和嵌入式系统。它提供了丰富的组件和模式,包括网络通信、事件处理、线程同步等功能,支持跨平台开发。ACE通过操作系统适配层屏蔽平台差异,提供类型安全的C++接口,并包含高级框架组件如Reactor、Service Configurator等。其优势在于可移植性、软件质量提升和效率优化。ACE还衍生出TAO(实时CORBA实现)和JAWS(高性能Web服务器)等中间件。该框架广泛应用于需要高性能通信和实时处理的领域。 阅读详情


ACE 开放源码工具包可以帮助开发人员创建健壮的可移植多线程应用程序。本文讨论创建使用 ACE 线程的应用程序的一些方法。

Adaptive Communication Environment (ACE) 是一个高性能、开放源码、面向对象的框架和 C++ 类库,它有助于简化网络应用程序的开发。ACE 工具包包括一个操作系统层和一个封装网络 API 的 C++ 外观(facades)集合。本文讨论如何使用 ACE 线程设计高性能、并发、面向对象的网络应用程序。对 ACE 的完整说明,包括如何下载和安装这个工具包,请参见 参考资料。

用于创建和管理线程的 ACE 类

在进程中生成和管理多个线程涉及下面的类:

ACE_Thread_Manager:这是负责创建、管理和同步线程的主要的类。每种操作系统在处理线程方面有细微差异,这个类对应用程序开发人员隐藏这些差异。

ACE_Sched_Params:使用这个类管理各个线程的调度优先级,调度优先级是在 ACE 源代码发行版的 ace/Sched_Params.h 头文件中定义的。可以采用不同的调度策略,可以是 “先到先服务” 的循环方式。

ACE_TSS:在多线程应用程序中使用全局变量会导致同步问题。ACE_TSS 类提供与线程相关的存储模式,可以对那些对于程序是全局的,但是对于每个线程私有的数据提供抽象。ACE_TSS 类提供 operator() 方法,这个方法提供与线程相关的数据。


了解线程管理器类

原生操作系统线程 API 是不可移植的:存在语法和语义差异。例如,UNIX® pthread_create() 和 Windows® CreateThread() 方法都创建线程,但是语法不一样。ACE_Thread_Manager 类提供以下功能:

它可以生成一个或更多线程,每个线程运行自己指定的函数。

它可以作为一个集合(称为 线程组)管理相关的线程。

它管理各个线程的调度优先级。

它允许在线程之间进行同步。

它可以修改线程属性,比如堆栈大小。

表 1 介绍 ACE_Thread_Manager 类的重要方法。


表 1. ACE_Thread_Manager 类的方法

方法名 说明

instance ACE_Thread_Manager 类是一个单实例类,使用这个方法访问线程管理器的惟一实例。

spawn 这个方法创建一个新线程,它的一个输入参数是 C/C++ 函数指针,这个函数执行应用程序的特定工作。

exit 这个方法终止一个线程,释放这个线程的所有资源。

spawn_n 这个方法创建属于同一个线程组的多个线程。

close 这个方法关闭已经创建的所有线程并释放它们的资源。

suspend 线程管理器暂停指定的线程。

resume 线程管理器恢复执行前面暂停的线程。

使用 ACE_Thread_Manager 类的变体

可以作为单实例类使用 ACE_Thread_Manager 类,也可以创建这个类的多个实例。对于单一实例,通过调用 instance 方法访问实例。如果需要管理多个线程组,可以创建不同的线程管理器类,每个类控制它自己的线程集。

清单 1 中的示例创建一个线程。


清单 1. 使用 ACE_Thread_Manager 类创建一个线程

#include "ace/Thread_Manager.h"

#include <iostream>


void thread_start(void* arg)

{

  std::cout << "Running thread..\n";

}


int ACE_TMAIN (int argc, ACE_TCHAR* argv[])

{

  ACE_Thread_Manager::instance()->spawn((ACE_THR_FUNC)thread_start);

  return 0;

}


清单 2 给出 spawn() 方法的原型(取自 ace/Thread_Manager.h)。


清单 2. ACE_Thread_Manager::spawn 方法的原型

int spawn (ACE_THR_FUNC func,

             void *arg = 0,

             long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,

             ACE_thread_t *t_id = 0,

             ACE_hthread_t *t_handle = 0,

             long priority = ACE_DEFAULT_THREAD_PRIORITY,

             int grp_id = -1,

             void *stack = 0,

             size_t stack_size = ACE_DEFAULT_THREAD_STACKSIZE,

             const char** thr_name = 0);


对于初学者来说,创建线程需要的参数数量似乎太多了,所以我们详细讨论一下各个参数和它们的作用:

ACE_THR_FUNC func:这是在生成线程时调用的函数。

void* arg:这是在生成线程时调用的函数的参数。void* 意味着用户可以传递应用程序特有的任何数据类型,甚至可以使用某种结构把多个参数组合成单一数据。

long flags:使用 flags 变量设置生成的线程的几个属性。各个属性都由单一位表示,按照 “或” 关系组合在一起。表 2 说明一些属性。

ACE_thread_t *t_id:使用这个函数访问创建的线程的 ID。每个线程具有惟一的 ID。

long priority:这是生成的线程的优先级。

int grp_id:如果提供这个参数,那么它表示生成的线程是否属于现有的某一线程组。如果传递 -1,那么创建新的线程组并在这个组中添加生成的线程。

void* stack:这是预先分配的堆栈区域的指针。如果提供 0,就请求操作系统提供生成的线程的堆栈区域。

size_t stack_size:这个参数指定线程堆栈的大小(字节数)。如果对于前一个参数(堆栈指针)指定了 0,那么请求操作系统提供大小为 stack_size 的堆栈区域。

const char** thr_name:这个参数只与支持线程命名的平台(比如 VxWorks)相关。对于 UNIX 平台,在大多数情况下忽略它。


表 2. 线程属性及其说明

线程创建标志 说明

THR_CANCEL_DISABLE 不允许取消这个线程。

THR_CANCEL_ENABLE 允许取消这个线程。

THR_DETACHED 创建异步线程。线程的退出状态对于其他任何线程不可用。当线程终止时,操作系统回收线程资源。

THR_JOINABLE 允许新线程的退出状态对于其他线程可用。这也是 ACE 创建的线程的默认属性。当这种线程终止时,操作系统不回收线程资源,直到其他线程联结它为止。

THR_NEW_LWP 创建显式的内核级线程(而不是用户级线程)。

THR_SUSPENDED 创建处于暂停状态的新线程。

清单 3 中的示例使用线程管理器类的 spawn_n 方法创建多个线程。


清单 3. 使用 ACE_Thread_Manager 类创建多个线程 

#include "ace/Thread_Manager.h"

#include <iostream>


void print (void* args)

{

  int id = ACE_Thread_Manager::instance()->thr_self();

  std::cout << "Thread Id: " << id << std::endl;

}


int ACE_TMAIN (int argc, ACE_TCHAR* argv[])

{

  ACE_Thread_Manager::instance()->spawn_n(

      4, (ACE_THR_FUNC) print, 0, THR_JOINABLE | THR_NEW_LWP);


  ACE_Thread_Manager::instance()->wait();

  return 0;

}


ACE 中的另一种线程创建机制

本节讨论 ACE 提供的另一种线程创建/管理机制。这种方法不需要对线程管理器进行显式的细粒度的控制。在默认情况下,每个进程在创建时有一个线程,这个线程在 main 函数开始时启动,在 main 结束时终止。其他线程都需要显式地创建。创建线程的另一种方式是创建预定义的 ACE_Task_Base 类的子类,然后覆盖 svc() 方法。新线程在 svc() 方法中启动,在 svc() 方法返回时终止。在进一步解释之前,请看一下 清单 4 所示的源代码。


清单 4. 使用 ACE_Task_Base::svc 创建线程

#include “ace/Task.h”


class Thread_1 : public ACE_Task_Base { 

  public: 

    virtual int svc( ) { 

       std::cout << “In child’s thread\n”;

       return 0;

    }

 };


int main ( )

{ 

   Thread_1 th1;

   th1.activate(THR_NEW_LWP|THR_JOINABLE);

   th1.wait();

   return 0;

}


在 svc() 方法中编写与应用程序相关的线程行为。通过调用 activate() 方法(在 ACE_Task_Base 类中声明和定义)执行线程。在激活线程之后,main() 函数等待子线程完成执行。这就是 wait() 方法的作用:在 Thread_1 执行完之前,主线程被阻塞。这一等待过程是必需的;否则,主线程会调度子线程并执行退出。在看到主线程退出时,C 运行时会销毁所有子线程;因此,子线程可能根本没有被调度或执行。

详细了解 ACE_Task_Base 类

下面详细看看 ACE_Task_Base 中的几个方法。

清单 5 给出 activate() 方法的原型。


清单 5. ACE_Task_Base::activate 方法的原型

virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,

                        int n_threads = 1,

                        int force_active = 0,

                        long priority = ACE_DEFAULT_THREAD_PRIORITY,

                        int grp_id = -1,

                        ACE_Task_Base *task = 0,

                        ACE_hthread_t thread_handles[ ] = 0,

                        void *stack[ ] = 0,

                        size_t stack_size[ ] = 0,

                        ACE_thread_t thread_ids[ ] = 0,

                        const char* thr_name[ ] = 0);


可以使用 activate() 方法创建一个或多个线程,每个线程调用相同的 svc() 方法,所有线程采用相同的优先级并具有相同的组 ID。下面简要介绍一些输入参数:

long flags:参见 表 2。

int n_threads:n_threads 指定要创建的线程的数量。

int force_active:如果这个标志是 True,而且存在这个任务已经生成的线程,那么新生成的所有线程会共享以前生成的线程的组 ID,忽略传递给 activate() 方法的值。

long priority:这个参数指定线程或线程集合的优先级。调度优先级值是与操作系统相关的,坚持使用默认值 ACE_DEFAULT_THREAD_PRIORITY 是最安全的。

ACE_hthread_t thread_handles:如果 thread_handles 不是零,那么在生成 n 个线程之后,会把各个线程句柄赋值给这个数组。

void* stack:如果指定这个参数,它指定一个指针数组,这些指针指向各个线程的堆栈基。

size_t stack_size:如果指定这个参数,它指定一个整数数组,这些整数表示各个线程堆栈的大小。

ACE_thread_t thread_ids:如果 thread_ids 不是零,那么这个参数是一个数组,其中包含 n 个新生成的线程的 ID。

清单 6 给出 ACE_Task_Base 类中另外几个有用的例程。


清单 6. ACE_Task_Base 中的其他例程

// Block the main thread until all threads of this task are completed 

virtual int wait (void);


// Suspend a task

virtual int suspend (void);


// Resume a suspended task.

virtual int resume (void);


// Gets the no. of active threads within the task

size_t thread_count (void) const;


// Returns the id of the last thread whose exit caused the thread count 

// of this task to 0. A zero return status implies that the result is 

// unknown. Maybe no threads are scheduled.

ACE_thread_t last_thread (void) const;


为了创建处于暂停状态的线程(而不是通过调用 suspend() 方法显式地暂停),需要向 activate() 方法传递 THR_SUSPENDED 标志。可以通过调用 resume() 方法恢复执行线程,见 清单 7。


清单 7. 暂停线程和恢复执行

Thread_1 th1;

th1.activate(THR_NEW_LWP|THR_JOINABLE|THR_SUSPENDED);

…// code in the main thread

th1.resume();

…// code continues in main thread


再看看线程标志

有两种线程:内核级线程和用户级线程。如果不带任何参数调用 activate() 方法,那么默认情况下创建内核级线程。内核级线程与操作系统直接交互,由内核级调度器调度。与此相反,用户级线程在进程范围内运行,为了完成某些任务,根据需要 “分配” 内核级线程。THR_NEW_LWP 标志(activate() 方法的默认参数)总是确保新创建的线程是内核级线程。

线程钩子

ACE 提供一个全局的线程启动钩子,这允许用户执行可以应用于所有线程的任何操作。为了创建启动钩子,需要创建预定义类 ACE_Thread_Hook 的子类并提供 start() 方法定义。start() 接受两个参数:一个用户定义函数的指针和传递给这个用户定义函数的 void*。为了注册钩子,需要调用静态方法 ACE_Thread_Hook::thread_hook,见 清单 8。


清单 8. 使用全局线程钩子

#include "ace/Task.h"

#include "ace/Thread_Hook.h"

#include <iostream>


class globalHook : public ACE_Thread_Hook {

  public:

    virtual ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func, void* arg) {

        std::cout << "In created thread\n";

        (*func)(arg);

    }

};


class Thread_1 : public ACE_Task_Base {

  public:

    virtual int svc( ) {

       std::cout << "In child's thread\n";

       return 0;

    }

 };



int ACE_TMAIN (int argc, ACE_TCHAR* argv[])

{

  globalHook g;

  ACE_Thread_Hook::thread_hook(&g);

  Thread_1 th1;

  th1.activate();

  th1.wait();

  return 0;

}


注意,自动传递给启动钩子的 ACE_THR_FUNC 指针是在执行线程的 activate() 方法时调用的相同函数。以上代码的输出是:

In created thread

In child’s thread


结束语

本文简要讨论了如何使用 ACE 框架创建和管理线程。ACE 框架还有其他一些有用的特性,比如互斥、用于同步的保护阻塞、共享内存和网络服务。详细信息请参见 参考资料。(责任编辑:A6)

35、探索ACE框架在现代网络编程中的应用与优化 本文深入探讨了ACE框架在现代网络编程中的应用与优化,包括Reactor、Proactor、服务配置器等核心模块的实际应用场景和性能优化方法。通过具体示例展示了如何使用ACE框架构建高效的Web服务器、日志管理系统等,并展望了ACE框架未来的发展方向。 阅读详情

相关推荐

12、探索高效网络编程:ACE框架深入解析

本文深入探讨了ACE框架的核心概念、设计模式及其在实际应用中的实现,帮助读者理解和掌握这一强大工具。ACE框架通过系统性复用网络应用程序软件,减少了开发工作量和开销,为C++开发者提供了宝贵的资源。文章涵盖了事件驱动编程、服务配置、并发处理、网络连接管理、异步I/O以及数据流处理等多个方面,并结合具体示例展示了ACE框架的应用场景和优化策略。

neovim7hacker的博客 607

ACE_Task介绍(生产者/消费者)v3.0

1ACE_Task 概述 ACE_Task是ACE中的任务或主动对象“处理结构”的基类。ACE使用此类来实现主动对象模式。所有希望成为“主动对象”的对象都必须由此类派生。同时可将它看作是更高级的、更为面向对象的线程。 ACE_Task处理的是对象,因此更有利于构造OO程序,产生更好的OO软件,而且,它还包括了一种用于 与其他任务通信的易于使用的机制。 ACE_Task

C++ 爱好者 make_it_simple888 6797

ACE 5.4.1网络编程框架实战详解

ACE(Adaptive Communication Environment)是一个面向对象的、开放源码的框架,广泛应用于高性能和实时通信服务程序的开发。它提供了丰富的网络通信和并发处理的组件,使得开发此类应用程序变得更加高效和简洁。ACE框架封装了底层的网络编程细节,为开发者提供了高级抽象,大大降低了编写复杂网络应用的难度。TCP/IP协议族,是互联网的基础,它定义了如何在主机和网络之间进行数据交换。

weixin_29092787的博客 1203

ACE线程安全与同步

 保护原语为了确保一致性,多线程程序必须在共享数据周围使用保护原语。Protection Primitives in ACEPrimitiveDescriptionACE_MutexWrapper class around the mutual-exclusion mechanism and used to provide a

1841

ACE-6.5.8开源高性能网络通信框架实战解析

本文还有配套的精品资源,点击获取 简介:ACE(Adaptive Communication Environment)是一个开源、跨平台的C++框架,专为构建高可靠性、高性能的网络通信系统而设计。本资源“ACE-6.5.8.zip”包含其最新版本源码,涵盖核心组件如ACE核心库、TAO分布式对象引擎、MPC代码生成工具、ACEXML解析器等,并提供丰富的示例、测试用例与完整文档。开发者可通过该框架深入掌握异步事件处理、多路复用、线程池、定时器队列等关键技术,适用于高性能服务器与分

weixin_35757191的博客 1035

ACE框架配置与入门全攻略

ACE(Adaptive Communication Environment)是一个开源的面向对象的框架,它提供了一系列的C++库,用于支持并发网络编程和分布式系统的开发。它使用现代C++特性,如模板和泛型编程,并强调多线程和同步机制。ACE框架广泛应用于需要高度可伸缩性和可移植性的系统中。中间件是一种软件,它位于操作系统和应用程序之间,以简化分布式应用的开发、运行和管理。中间件屏蔽了网络的复杂性,提供了统一的接口,使得开发者能够专注于业务逻辑的实现而不是底层通信的细节。

weixin_33506815的博客 1718

ACE的线程创建

activate();/*默认创建一个线程*/

EveryDayOneHour的博客 501

射频工程师笔记---射频通信基础

回顾一下移动通信技术的发展,其实是互联网和通信技术的融合过程。在这个过程中,很多应用都在不断加入其中。比如计算机跟通信的融合产生了互联网、互联网跟手机的融合带来了移动互联网。手机可以看杂志、看视频、听音乐,于是又出现了内容服务产业;再后来,电视音箱等设备也能联网,于是网络跟家电又产生了融合。所以应用的出现总是在融合其他产业。在1995年,比尔·盖茨在《未来之路》一书中首次提出:在未来...

多年硬件从业经历,热爱学习,记录生活! 2万+

ACE框架ACE_Task_Base的子类

子类A的实力对象a,需调用父类的activate()以启动该子类线程,从而执行svc中的内容。子类A需重写ACE_Task_Base的虚函数svc(),该函数是该线程类的执行内容;子类A继承于ACE_Task_Base。

m0_46104251的博客 593

通达信大单资金实时监控与播报插件:股票分析的实用利器——大红球

本文介绍了一款专为通达信软件设计的大单资金实时监控与播报插件,该插件以其傻瓜式操作和入门级特性在股民中广受欢迎。插件核心功能包括与通达信版面的无缝联动、大单金额范围的自定义设置、资金流动的可视化展示以及智能声音播报等。其技术架构基于本地网页形式,自带分时图显示功能,数据实时更新且无需L2账户,承诺永久免费升级。插件通过红绿球的大小和颜色直观展示资金规模与买卖方向,顶端全局统计功能提供宏观资金流动分析。尽管插件数据具有较高参考价值,但投资者仍需结合其他因素进行综合判断。插件界面可自适应调整,提供个性化使用体验

guleba的博客 6592

M2DGR数据集在主流SLAM框架中的实战配置指南:从ORB-SLAM到FAST-LIO的完整流程

本文提供了M2DGR多传感器数据集在主流SLAM框架中的实战配置指南。详细介绍了从ORB-SLAM、VINS-Mono等视觉/视觉惯性框架,到A-LOAM、FAST-LIO等激光/激光惯性框架的完整配置流程、参数调整要点及常见问题解决方案。通过实际测试对比,分析了各算法在M2DGR数据集上的表现,为机器人定位与建图研究提供了宝贵的实战经验。

k9l0m1的博客 481

使用ACE 库框架在UNIX中开发高性能并发应用

<br /> <br />使用 ACE 库框架在 UNIX 中开发高性能并发应用<br /><br /><br />ACE 开放源码工具包可以帮助开发人员创建健壮的可移植多线程应用程序。本文讨论创建使用 ACE 线程的应用程序的一些方法。<br />Adaptive Communication Environment (ACE) 是一个高性能、开放源码、面向对象的框架和 C++ 类库,它有助于简化网络应用程序的开发。ACE 工具包包括一个操作系统层和一个封装网络 API 的 C++ 外观(facades)集

梦想照进现实 891

基于微信小程序的答题系统

学习视频:《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!5812)]《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

2401_83330193的博客 499

ACE简介

导读:   (转载自中国互动出版网,http://www.china-pub.com/computers/emook/1111/info.htm)   文章摘要:   ADAPTIVE Communication Environment (ACE) 是一种免费开放原代码的面向对象框架结构,该结构实现了许多并行通信软件的核心设计模式. ACE提供丰富的C++ wrapper facades,

zhangyb54007的专栏 1546

AD24层次原理图设计避坑指南:如何解决端口连接与自动交叉引用问题

本文深入解析AD24层次原理图设计的核心机制,聚焦端口连接错误、自动交叉引用干扰等常见问题。通过对比自上而下与自下而上设计流程,提供端口类型匹配、命名规范等实用解决方案,并指导如何关闭烦人的红色框线视觉干扰,帮助工程师高效避坑,实现复杂系统的模块化设计。

wdx01234567的博客 615

SD - WAN:企业出海的网络加速器

例如,一家中国的跨境电商企业,在欧美市场的促销活动期间,借助 SD - WAN 技术,即使面对海量订单数据的交互,也能确保欧美客户在浏览商品、下单支付时感受到近乎本地网络的流畅体验,大大提升了客户满意度,稳住了销售增速。企业无需在海外本地部署大量冗余服务器,只需依托云台,借助 SD - WAN 快速稳定的网络连接,即可轻松实现业务拓展,进一步精简运营架构,提升整体效能。在未来,随着技术的不断演进和企业出海需求的持续增长,SD - WAN 将持续赋能,助力更多企业在全球市场扬帆远航,书写辉煌篇章。

idcicp_com的博客 446
上一篇: ace中tcp连接
下一篇: ACE主动对象模式学习
mopname
博客等级 码龄15年 0粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值