ACE框架:ACE_Task

ACE(Adaptive Communication Environment)是一个开源的、面向对象的工具包和框架,旨在简化复杂网络应用和服务的开发。它提供了一个丰富的集合,包括通信软件模式的实现、服务、以及用于并发编程、事件调度、线程池管理等的类库。ACE 支持广泛的平台和操作系统,使其成为构建高性能、可移植的网络应用程序的理想选择。

ACE 的主要特点

  1. 跨平台支持:能够在多种操作系统上运行,包括 Windows、Linux、Unix 等。
  2. 丰富的通信协议支持:支持 TCP/IP、UDP、SCTP 等多种网络协议。
  3. 灵活的服务配置:通过使用 Reactor 和 Proactor 模式,能够方便地处理异步事件。
  4. 高效的并发控制:提供了线程池、互斥锁、读写锁等多种同步机制来帮助开发者编写高效且安全的多线程程序。
  5. 内存管理:提供自动化的内存管理工具,减少内存泄漏的风险。

基本概念与组件

  • Reactor 模式:一个事件处理循环,允许应用程序注册感兴趣的事件,并在这些事件发生时得到通知。适用于处理大量短连接或需要快速响应的场景。

  • Proactor 模式:一种异步 I/O 模型,允许执行非阻塞操作并在线程池中处理完成的通知。适用于长连接或需要高性能的场景。

  • ACE_Task:实现了主动对象(Active Object)的概念,使得每个任务都可以在独立的线程中运行,适合于需要长期运行的任务或后台处理。

  • Connector/Acceptor 模式:用于解耦网络连接建立过程中的客户端和服务器端逻辑,便于扩展和维护。

使用 ACE 创建一个简单的 TCP 服务器

下面是一个使用 ACE 构建的基本 TCP 服务器示例:

#include "ace/INET_Addr.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
#include "ace/Acceptor.h"
#include "ace/Svc_Handler.h"
#include <iostream>

class Echo_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> {
public:
    // 当有数据到达时被调用
    int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE) override {
        char buf[1024];
        size_t len = this->peer().recv(buf, sizeof(buf));
        if (len > 0) {
            std::cout << "Received: " << std::string(buf, len) << std::endl;
            this->peer().send(buf, len); // 回显消息
        } else {
            this->reactor()->remove_handler(this);
            delete this; // 关闭连接并删除自身
        }
        return 0;
    }

    // 连接关闭时被调用
    int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE,
                     ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) override {
        this->peer().close();
        return 0;
    }
};

typedef ACE_Acceptor<Echo_Handler, ACE_SOCK_ACCEPTOR> Echo_Acceptor;

int main() {
    ACE_INET_Addr port_to_listen(12345, ACE_LOCALHOST);
    Echo_Acceptor acceptor(port_to_listen);

    ACE_Reactor::instance()->run_reactor_event_loop();

    return 0;
}

ACE_Task

ACE_Task<ACE_MT_SYNCH> 是 ACE(Adaptive Communication Environment)框架中的一个模板类,用于实现多线程任务处理。这个类提供了对多线程的支持,并允许你创建可以主动运行的线程,以及通过消息队列与其他线程进行通信的任务。ACE_MT_SYNCH 是一个模板参数,指定了使用多线程同步机制。

基本概念

  • ACE_Task:这是一个核心类,提供了一个简单的接口来实现主动对象(active objects)。主动对象是指那些在其自己的控制线程中执行操作的对象。
  • ACE_MT_SYNCH:这是一个模板参数,它决定了在多线程环境中使用的同步机制。使用 ACE_MT_SYNCH 作为模板参数意味着将使用适合多线程环境的锁和其他同步原语。

实现一个多线程任务

以下是一个简单的例子,展示了如何使用 ACE_Task<ACE_MT_SYNCH> 来创建和运行一个多线程任务。

示例代码
#include "ace/config.h"
#include "ace/Task.h"
#include <iostream>
#include <ace/Init_ACE.h>

class MyTask : public ACE_Task<ACE_MT_SYNCH> {
public:
	//MyTask() = default;
	MyTask(int maxThread)
		: m_maxThread(maxThread)
		, m_thr_ids(new ACE_thread_t[maxThread])
	{

	}


	int open(void* = nullptr) override {
		// Called when activate() is invoked. You can perform any initialization here.
		std::cout << "Task started." << std::endl;

		msg_queue()->high_water_mark(50 * 1024 * 1024);

		///* -- WSAStartup -- */
		WORD version = MAKEWORD(2, 2);
		WSADATA data;

		if (WSAStartup(version, &data) != 0)
		{
			return -1;
		}

		return activate(
			THR_NEW_LWP,						// -> flags
			m_maxThread,						// -> n_threads
			0,									// -> force_active
			ACE_DEFAULT_THREAD_PRIORITY,		// -> priority
			-1,									// -> grp_id
			NULL,								// -> task
			NULL,								// -> thread_handles
			NULL,								// -> stack
			NULL,								// -> stack_size
			m_thr_ids,							// -> thread_ids
			NULL								// -> thr_name
		);


		return 0;
	}

	int svc() override {
		// The main thread loop of the task.
		for (int i = 0; i < 5; ++i) {
			std::cout << "Working in thread: " << thr_mgr()->thr_self()/*this->thr_self()*/ << std::endl;
			ACE_OS::sleep(1); // Simulate work by sleeping for a second
		}
		std::cout << "Thread finished." << std::endl;
		return 0;
	}

	int close(u_long flags = 0) override {
		// Called when the task is shutting down.
		std::cout << "Task closed." << std::endl;
		return 0;
	}

private:
	int m_maxThread;								/// 线程数
	ACE_thread_t *m_thr_ids;						/// 线程ID
};

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

	MyTask my_task(3);

	// Activate the task with 3 threads.
	//if (my_task.activate(THR_NEW_LWP | THR_JOINABLE, 3) == -1) {
	//	std::cerr << "Failed to activate task" << std::endl;
	//	return -1;
	//}
	my_task.open();

	// Wait for all threads to finish their work before exiting.
	my_task.wait();

	std::cout << "All threads have completed their work." << std::endl;
	return 0;
}
关键函数分析
  • open 方法:当调用 activate() 方法时会触发此方法。你可以在这里进行一些初始化工作。
  • svc 方法:这是每个线程的主循环。在这个方法中,你可以编写需要并行执行的代码。在这个例子中,我们简单地打印了当前线程ID,并模拟了一秒钟的工作。
  • close 方法:当任务关闭时被调用,可以用来清理资源。
  • activate 方法:启动任务,参数包括线程属性和要创建的线程数。在这个例子中,我们创建了3个线程。
  • wait 方法:等待所有由 activate() 创建的线程完成它们的工作。

【注】:VS工程配置,预处理器定义添加

_WINSOCK_DEPRECATED_NO_WARNINGS;

_CRT_SECURE_NO_WARNINGS;

WIN32;

_WIN32;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值