`
zsxxsz
  • 浏览: 452020 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用 acl_cpp 库编写多线程程序

阅读更多

      在 《利用ACL库开发高并发半驻留式线程池程序》中介绍了如何使用 C 版本的 acl 线程库编写多线程程序,本文将会介绍如何使用 C++ 版本的 acl 线程库编写多线程程序,虽然 C++ 版 acl 线程库基于 C 版的线程库,但却提供了更为清晰简洁的接口定义(很多地方参考了 JAVA 的线程接口定义)。下面是一个简单的使用线程的例子:

#include "acl_cpp/lib_acl.hpp"

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

// 子线程类定义
class mythread : public acl::thread
{
public:
	mythread() {}
	~mythread() {}
protected:
	// 基类纯虚函数,当在主线程中调用线程实例的 start 函数时
	// 该虚函数将会被调用
	virtual void* run()
	{
		const char* myname = "run";
		printf("%s: thread id: %lu, %lu\r\n",
			myname, thread_id(), acl::thread::thread_self());
		return NULL;
	}
};

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

static void test_thread(void)
{
	const char* myname = "test_thread";
	mythread thr;  // 子线程对象实例

	// 设置线程的属性为非分离方式,以便于下面可以调用 wait
	// 等待线程结束
	thr.set_detachable(false);

	// 启动一个子线程
	if (thr.start() == false)
	{
		printf("start thread failed\r\n");
		return;
	}

	printf("%s: thread id is %lu, main thread id: %lu\r\n",
		myname, thr.thread_id(), acl::thread::thread_self());

	// 等待子线程运行结束
	if (thr.wait(NULL) == false)
		printf("wait thread failed\r\n");
	else
		printf("wait thread ok\r\n");
}

int main(void)
{
	// 初始化 acl 库
	acl::acl_cpp_init();
	test_thread();
#ifdef WIN32
	printf("enter any key to exit ...\r\n");
	getchar();
#endif
	return 0;
}

 

      从上面的示例来看,使用 acl 的线程库创建使用线程还是非常简单的。打开 lib_acl_cpp/include/acl_cpp/stdlib/thread.hpp 文件,可以看到线程类的声明,其中有两个基类:acl::thread 与 acl::thread_job,在 基类 acl::thread_job 中有一个纯虚函数 run(),acl::thread 也继承自 acl::thread_job,用户的线程类需要继承 acl::thread,并且需要实现基类 acl::thread_job 的纯虚函数: run()。当应用在主线程中调用线程实例的 start() 函数时,acl 线程库内部便创建一个子线程,子线程被创建后线程对象的 run() 函数便被调用。下面是 acl::thread 类中几个主要的方法定义:

 

class thread_job
{
public:
	thread_job() {}
	virtual ~thread_job() {}

	/**
	 * 纯虚函数,子类必须实现此函数,该函数在子线程中执行
	 * @return {void*} 线程退出前返回的参数
	 */
	virtual void* run() = 0;
};

class thread : public thread_job
{
public:
	thread();
	virtual ~thread();
	
	/**
	 * 开始启动线程过程,一旦该函数被调用,则会立即启动一个新的
	 * 子线程,在子线程中执行基类 thread_job::run 过程
	 * @return {bool} 是否成功创建线程
	 */
	bool start();

	/**
	 * 当创建线程时为非 detachable 状态,则可以调用此函数
	 * 等待线程结束;否则,若创建线程时为 detachable 状态
	 * 在调用本函数时将会报错
	 * @param out {void**} 当该参数非空指针时,该参数用来存放
	 *  线程退出前返回的参数
	 * @return {bool} 是否成功
	 */
	bool wait(void** out = NULL);

	/**
	 * 在调用 start 前调用此函数可以设置所创建线程是否为
	 * 分离 (detachable) 状态;如果未调用此函数,则所创建
	 * 的线程默认为分离状态
	 * @param yes {bool} 是否为分离状态
	 * @return {thread&}
	 */
	thread& set_detachable(bool yes);

	/**
	 * 在调用 start 前调用此函数可以设置所创建线程的堆栈大小
	 * @param size {size_t} 线程堆栈大小,当该值为 0 或未
	 *  调用此函数,则所创建的线程堆栈大小为系统的默认值
	 * @return {thread&}
	 */
	thread& set_stacksize(size_t size);

	/**
	 * 在调用 start 后调用此函数可以获得所创建线程的 id 号
	 * @return {unsigned long}
	 */
	unsigned long thread_id() const;

	/**
	 * 当前调用者所在线程的线程 id 号
	 * @return {unsigned long}
	 */
	static unsigned long thread_self();
        ....
};

       从上面的线程示例及 acl::thread 的类定义,也许有人会觉得应该把 acl::thread_job 的纯虚方法:run() 放在 acl::thread 类中,甚至觉得 acl::thread_job 类是多余的,但是因为 acl 库中还支持线程池方式,则 acl::thread_job 就显得很有必要了。在 lib_acl_cpp\include\acl_cpp\stdlib\thread_pool.hpp 头文件中可以看到 acl 的线程池类 acl::thread_pool 的声明,该类的主要函数接口如下:

 

 

class thread_pool
{
	/**
	 * 启动线程池,在创建线程池对象后,必须首先调用此函数以启动线程池
	 */
	void start();

	/**
	 * 停止并销毁线程池,并释放线程池资源,调用此函数可以使所有子线程退出,
	 * 但并不释放本实例,如果该类实例是动态分配的则用户应该自释放类实例,
	 * 在调用本函数后,如果想重启线程池过程,则必须重新调用 start 过程
	 */
	void stop();

	/**
	 * 等待线程池中的所有线程池执行完所有任务
	 */
	void wait();

	/**
	 * 将一个任务交给线程池中的一个线程去执行,线程池中的
	 * 线程会执行该任务中的 run 函数
	 * @param job {thread_job*} 线程任务
	 * @return {bool} 是否成功
	 */
	bool run(thread_job* job);

	/**
	 * 将一个任务交给线程池中的一个线程去执行,线程池中的
	 * 线程会执行该任务中的 run 函数;该函数功能与 run 功能完全相同,只是为了
	 * 使 JAVA 程序员看起来更为熟悉才提供了此接口
	 * @param job {thread_job*} 线程任务
	 * @return {bool} 是否成功
	 */
	bool execute(thread_job* job);

	/**
	 * 在调用 start 前调用此函数可以设置所创建线程的堆栈大小
	 * @param size {size_t} 线程堆栈大小,当该值为 0 或未
	 *  调用此函数,则所创建的线程堆栈大小为系统的默认值
	 * @return {thread&}
	 */
	thread_pool& set_stacksize(size_t size);

	/**
	 * 设置线程池最大线程个数限制
	 * @param max {size_t} 最大线程数,如果不调用此函数,则内部缺省值为 100
	 * @return {thread_pool&}
	 */
	thread_pool& set_limit(size_t max);

	/**
	 * 设置线程池中空闲线程的超时退出时间
	 * @param ttl {int} 空闲超时时间(秒),如果不调用此函数,则内部缺省为 0
	 * @return {thread_pool&}
	 */
	thread_pool& set_idle(int ttl);
        ......
};

       这些接口定义也相对简单,下面给出一个使用线程池的例子:

// 线程工作类
class myjob : public acl::thread_job
{
public:
	myjob() {}
	~myjob() {}

protected:
	// 基类中的纯虚函数
	virtual void* run()
	{
		const char* myname = "run";
		printf("%s: thread id: %lu\r\n",
			myname, acl::thread::thread_self());
		return NULL;
	}
};

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

// 线程池类
class mythread_pool : public acl::thread_pool
{
public:
	mythread_pool() {}
	~mythread_pool()
	{
		printf("thread pool destroy now, tid: %lu\r\n",
			acl::thread::thread_self());
	}

protected:
	// 基类虚函数,当子线程被创建时该虚函数将被调用
	virtual bool thread_on_init()
	{
		const char* myname = "thread_on_init";

		printf("%s: curr tid: %lu\r\n", myname,
			acl::thread::thread_self());
		return true;
	}

	// 基类虚函数,当子线程退出前该虚函数将被调用
	virtual void thread_on_exit()
	{
		const char* myname = "thread_on_exit";

		printf("%s: curr tid: %lu\r\n", myname,
			acl::thread::thread_self());
	}
};

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

void test()
{
	acl::thread_pool* threads = new mythread_pool();
	threads->start();  // 启动线程池过程

	acl::thread_job *job1= new myjob, *job2 = new myjob;
	threads->execute(job1);
	threads->execute(job2);

	// 为了保证 job1, job2动态内存被正确释放,
	// 必须调用 threads->stop 等待子线程运行结束后在
	// 主线程中将其释放
	threads->stop();
	delete threads;

	// 在主线程中释放动态分配的对象
	delete job1;
	delete job2;
}

       如上例所示,在使用 acl 的C++版本线程池类库时,必须定义一个线程工作类(继承自 acl::thread_job)并实现基类的纯虚函数:run();另外,在使用线程池时,如果想要在线程创建时初始化一些线程局部变量以及在线程退出前释放一些线程局部变量,则可以定义 acl::thread_pool 的子类,实现基类中的 thread_on_init 和 thread_on_exit 方法,如果不需要,则可以直接使用 acl::thread_pool 类对象。

 

下载:http://sourceforge.net/projects/acl/

svn:svn://svn.code.sf.net/p/acl/code/trunk

github:https://github.com/acl-dev/acl

QQ 群:242722074 

 

0
0
分享到:
评论

相关推荐

    acl_cpp:用于win32 / linux,服务器框架,HttpServlet的功能强大的c ++库-开源

    acl_cpp(已包含在acl项目中:https://sourceforge.net/projects/acl/,请从acl项目url下载)是acl的c ++包装库,并且acl_cpp比acl具有更多有用的功能,例如例如流式mime解析,处理程序套接字支持以及db(mysql和...

    acl_cpp:一个强大的 c++ 库,用于 win32/linux、服务器框架、HttpServlet-开源

    acl_cpp(已包含在acl项目:https://sourceforge.net/projects/acl/,请从acl项目url下载)是acl的c++封装库,acl_cpp比acl有很多有用的功能,比如如流式mime解析、handler socket支持、db(mysql和sqlite)池接口、...

    基于acl库封装c\c++ 的redis-client客户端源码

    redis-acl\lib_acl_cpp\samples\redis路径下,把lib_acl_vc2010d.lib、lib_acl_cpp_vc2010d.lib放到 \redis-acl\lib_acl_cpp\samples\redis\redisclient路径下: 依赖的库 需要下载开源 源码编出来 : svn://svn....

    acl-master.zip_ACL库_c++ acl_git acl-master

    acl_cpp 是基于 acl 库的 C++ 库,包括 MIIME 解析、Handlersocket 客户端库、数据库连接池(支持mysql/sqlite)、WEB 编程、数据库编程、阻塞/非阻塞数据流等内容。

    acl C++跨平台库.rar

    主要包括:lib_acl(用 C 语言写的基础库)、lib_protocol(用 C 语言写的一些网络应用协议库)、lib_acl_cpp(用 C++ 语言编写,封装了 lib_acl/lib_protocol 两个库,同时增加更多实用的功能库)、 lib_fiber(用 ...

    Python库 | acl_iitbbs-0.1-py3-none-any.whl

    Python库的设计通常遵循模块化原则,因此`acl_iitbbs`可能包含多个子模块,每个子模块都有特定的功能,如登录认证、帖子检索、分类浏览、用户管理等。为了深入了解这个库,我们需要查看其文档或源代码,了解它的API...

    acl.2.1.2.8.src.2012.7.2.zip_ACL_ACL_http_http json_协议

    ACL(Access Control List)框架库是一个专为C语言设计的开源库,它的核心目标是提供一个高效且灵活的服务器开发框架。这个库包含了多种关键组件,使得开发者在构建网络服务时能够快速、稳定地实现复杂的功能。以下...

    CISCO_ACL__思科_访问控制列表

    CISCO_ACL__思科_访问控制列表

    acl.rar_ACL_Agent_jade_jade agent_jade java

    在这个“ACL_Agent_jade_jade_agent_jade_java”主题中,我们将探讨如何在JADE上构建和配置agent,以及它们如何使用ACL进行通信。 首先,了解JADE的基本结构是至关重要的。JADE由几个核心组件组成,包括:Agent容器...

    acl.zip_ACL_权限控制

    在这个“acl.zip_ACL_权限控制”的压缩包中,我们有四个PHP文件:p2.php、acl_1.php、p3.php和p1.php。这些文件很可能是用来演示如何通过HTTP GET请求参数实现简单的ACL权限控制。下面将详细解释ACL的概念以及如何在...

    Acl_pong-master.zip_it

    《ACL_Pong-Master:一款基于IT技术的乒乓游戏解析》 在信息技术(IT)领域,游戏开发一直是吸引众多开发者和玩家的重要分支。今天我们要探讨的是"Acl_pong-master"项目,这是一款以乒乓球为主题的简单游戏,让我们...

    posix_acl.rar_V2

    开发者可以利用这个库来编写需要精确控制文件访问权限的程序,例如在多用户环境或共享文件系统中。 总的来说,"posix_acl.rar_V2"提供的源代码和头文件是开发和管理系统级权限的关键工具,它们使得开发者能够深入...

    acl_mysql_util

    acl_mysql_util是一个针对MySQL数据库和ACL(Access Control List,访问控制列表)的实用工具库,它为开发者提供了方便的接口,以便在应用中更高效、更安全地进行数据操作。这个库是基于MySQL的原生接口进行封装,...

    code_for_ACL_2020_paper_FLAT_Chinese_NER_Using_F

    code_for_ACL_2020_paper_FLAT_Chinese_NER_Using_F_Flat-Lattice-Transformer

    acl-3.0.19

    lib_acl(纯C开发的基础库,主要包含网络通信及服务器编程框架以及其它丰富的功能)、lib_protocol(包含 HTTP/PING/SMTP 通信协议的C语言实现)、lib_acl_cpp(基于 lib_acl 及 lib_protocol 两个C库,提供了更为强大的...

    posix_acl.rar_aclfun

    2. `acl_get_entry()`: 此函数用于获取ACL中的特定条目,可能用于读取已有的权限设置。 3. `acl_set_entry()`: 这个函数用来修改ACL中的条目,比如更新特定用户的权限。 4. `acl_add_entry()`: 添加新的ACL条目,...

    acl-master_网络通信框架_aclmaster_

    acl 工程是一个跨平台的通用网络通信库,同时提供更多的其它有价值功能。通过该库,用户可以非常容易地编写支持多种模式的服务器程序、WEB 应用程序以及数据库应用程序。此外,该库还提供了 XML/JSON/MIME 编码及...

    acl.rar_ACL_control

    在IT行业中,访问控制列表(Access Control List,简称ACL)是一种重要的安全机制,它用于管理对资源的访问权限。QEMU,全称Quick Emulator,是一个功能强大的开源虚拟化软件,能够模拟各种CPU架构和硬件环境。在...

    luyouqi.rar_ACL_路由器

    本压缩包文件"luyouqi.rar_ACL_路由器"提供了关于标准ACL配置的详细资料,旨在帮助用户理解和实施路由器的ACL设置。 首先,我们来看"标准ACL"的概念。标准ACL是基于源IP地址进行过滤的规则集合,允许或拒绝特定网络...

Global site tag (gtag.js) - Google Analytics