C++进阶学习——线程基类的设计(Linux)

此示例是在Linux环境下(使用Linux系统编程线程相关函数)测试,文件说明如下:

  • ThreadBase.cpp, ThreadBase.h为线程基类
  • ThreadDerive.cpp, ThreadDerive.h为测试派生类
  • main.cpp为测试程序

ThreadBase.h内容如下:

#ifndef __THREADBASE_H__
#define __THREADBASE_H__
#include <pthread.h>

//线程基类
class ThreadBase
{
public:
	ThreadBase(); //构造函数
	virtual ~ThreadBase(); //虚析构函数

	virtual int start(); //启动线程
	virtual void routine(); //线程的运行函数,由派生类实现
	virtual pthread_t self(); //获取当前线程的线程号
	virtual int equal(pthread_t t); //比较线程号是否相等
	virtual int detach(); //分离线程
	virtual int join(pthread_t t); //连接线程
	virtual int exit(); //线程退出
	virtual int cancel(pthread_t t); //取消线程
	virtual int destroy(); //销毁线程

private:
	static void cleaner(void *pHandle); //线程清理函数
	static void *work(void *pHandle); //线程回调函数

private:
	pthread_attr_t  t_attr; //线程属性
	pthread_t tid; //线程号

};

#endif

ThreadBase.cpp内容如下:

#include <stdio.h>
#include "ThreadBase.h"

//构造函数,通过参数列表方式给线程号初始化为0
ThreadBase::ThreadBase():tid(0)
{

}

//虚析构函数
ThreadBase::~ThreadBase()
{
	printf("~ThreadBase\n");
}

/****************************************************************
@功能:启动线程
@参数:无
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::start()
{
	int ret = 0;

	size_t nsize = 1024*20; //20k
	ret = pthread_attr_init(&t_attr); //初始化线程属性
	if(ret != 0)
	{
		perror("pthread_attr_init");
		return -1;
	}

	//设置线程的堆栈大小
	ret = pthread_attr_setstacksize(&t_attr, nsize);
	if(ret != 0)
	{
		perror("pthread_attr_getstacksize");
		 return -1;
	}

	//创建线程
	return pthread_create(&tid, &t_attr, work, this);
}

/****************************************************************
@功能:线程的运行函数,此处为空,由派生类实现
@参数:无
@返回值: 无
******************************************************************/
void ThreadBase::routine()
{

}

/****************************************************************
@功能:获取当前线程的线程号
@参数:无
@返回值: 线程号
******************************************************************/
pthread_t ThreadBase::self()
{
	if(!tid)
	{
		tid = pthread_self(); //获取线程号
	}

	return tid;
}

/****************************************************************
@功能:比较线程号是否相等
@参数:待比较的线程号
@返回值: 相等:0,不相等:-1
******************************************************************/
int ThreadBase::equal(pthread_t t)
{
	int ret = 0;
	ret = pthread_equal(tid, t);
	return (ret)?0:-1;
}

/****************************************************************
@功能:分离线程,待线程结束时让系统自动回收其资源
@参数:无
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::detach()
{
	return pthread_detach(tid);
}

/****************************************************************
@功能:连接线程,等待指定的线程结束,并回收其资源
@参数:无
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::join(pthread_t t)
{
	return pthread_join(t, NULL);
}

/****************************************************************
@功能:线程退出
@参数:无
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::exit()
{
	int ret = 0;
	pthread_exit(NULL);
	return ret;
}

/****************************************************************
@功能:取消线程
@参数:线程号
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::cancel(pthread_t t)
{
	return  pthread_cancel(t);
}

/****************************************************************
@功能:销毁线程
@参数:线程号
@返回值: 成功:0,失败:-1
******************************************************************/
int ThreadBase::destroy()
{
	return cancel(tid);
}

/****************************************************************
@功能:线程清理函数
@参数:线程句柄
@返回值: 无
******************************************************************/
void ThreadBase::cleaner(void *pHandle)
{
    ThreadBase *p = (ThreadBase *)pHandle;
    delete p;
    p = NULL;
    printf("after clean\n");
}

/****************************************************************
@功能:线程回调函数
@参数:线程句柄
@返回值: 无
******************************************************************/
void *ThreadBase::work(void *pHandle)
{
	ThreadBase* pThread = (ThreadBase *)pHandle;

	//注册线程处理函数
	pthread_cleanup_push(cleaner, pHandle);

	pThread->routine(); //线程运行函数

	//线程资源释放,参数为非0
	pthread_cleanup_pop(1);

	return NULL;
}

ThreadDerive.h内容如下:

#ifndef _THREADDERIVE_H_
#define _THREADDERIVE_H_
#include "ThreadBase.h"

//派生类ThreadDerive,公有继承于ThreadBase
class ThreadDerive: public ThreadBase
{
public:
	ThreadDerive();
	~ThreadDerive();

	void init(const int n, const char *str);
	void routine();

private:
	char buf[512];
	int num;

};

#endif

ThreadDerive.cpp内容如下:

#include "ThreadDerive.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>

//构造函数
ThreadDerive::ThreadDerive()
{
	num = 0;
	memset(buf, 0, sizeof(buf));
}

//析构函数
ThreadDerive::~ThreadDerive()
{
	printf("~ThreadDerive\n");
}

//初始化数据
void ThreadDerive::init(const int n, const char *str)
{
	num = n;
	strcpy(buf, str);
}

//线程运行函数
void ThreadDerive::routine()
{
	printf("I am running\n");
	for(int i = 0; i < num; i++)
	{
		printf("buf = %s, num = %d\n", buf, num);
		sleep(1);
	}
}

main.cpp内容如下:

#include "ThreadDerive.h"
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>

int main()
{
	//一定要动态分配空间,因为基类清理时使用了detele
	//不需要人为detele,线程基类已经做处理
	ThreadDerive *derive = new ThreadDerive;
	derive->init(5, "i am mike");

	derive->start();
	//usleep(1000*100);	//保证线程已经执行
	pthread_t tid = derive->self();
	printf("tid ========= %lu\n", tid);

	derive->detach(); //分离线程

	while(1)
	{
		printf("in the main fun\n");
		sleep(1);
	}

	return 0;
}

编译运行结果如下:

本教程示例代码下载请点此链接:http://download.csdn.net/detail/tennysonsky

版权声明:本博客文章,大多是本人整理编写,或在网络中收集,转载请注明出处!!

时间: 2024-12-30 18:13:11

C++进阶学习——线程基类的设计(Linux)的相关文章

C#WinForm线程基类

在CS模式开发中一般我们需要用到大量的线程来处理比较耗时的操作,以防止界面假死带来不好的体验效果,下面我将我定义的线程基类给大家参考下,如有问题欢迎指正. 基类代码 1 #region 方法有返回值 2 /// <summary> 3 /// 功能描述:多线程执行方法,方法有返回值 4 /// 作 者:huangzh 5 /// 创建日期:2017-03-29 17:44:26 6 /// 任务编号:MES 7 /// </summary> 8 /// <param name

线程基类 转载滴,收藏一下

转载请注明出处.http://www.cnblogs.com/zetee/p/3486993.html 多线程这个概念大家都很熟悉,对于winform的开发人员来说.用的还是多的.但估计都是用Timer,或者backgroundWorker. 你是否曾经想过,写一个基类,然后....一用到多线程的时候,就马上能用上呢. 没错,福利来了,这面我为大家写了多线程的一个基类.只有你用到多线程,下面的代码肯定能帮到你很多忙 /// <summary> /// 下载线程对了. /// </summ

基类的设计

鉴于json数据传输的使用,可以在实体类基础上设计基类 public abstract class BaseModel implements Serializable{  private static final long serialVersionUID=1L;      //==============json===============//  /**   * 从JSONObject中读取字段   * @param obj   */  public BaseModel parseJson(

C++学习21 基类和派生类的赋值

在C/C++中,经常会发生数据类型转换,例如整型数据可以赋值给浮点型变量,在赋值之前,先把整型数据转换为浮点型:反过来,浮点型数据也可以赋值给整型变量. 数据类型转换的前提是,编译器知道如何对数据进行取舍.例如: int a = 10.9; printf("%d\n", a); 输出结果为 10,编译器会将小数部分直接丢掉(不是四舍五入).再如: float b = 10; printf("%f\n", b); 输出结果为 10.000000,编译器会自动添加小数部

进阶学习,如何无代码设计一款美观且实用的网站?

作为一门新兴的边缘性职业,网站设计既要从外观上创意,又要适当结合图形.版面及交互设计等相关原理,使得它成为一门独特且令人神往的艺术.毫无疑问,好的设计能让网站在诸多站点中脱颖而出,优秀的创意和表现方式能给浏览者留下深刻的印象,从而持续间接地增加网站访问流量和转换率.然而,要设计出一款兼顾"颜值和实用性"的个人/企业网站并不容易,更不用说让设计想法落地实现出来对大多数人说更是一项艰巨的任务. 那到底如何才能在时间和技能有限的情况下,设计出一款令人满意甚至网红的网站呢?小编认为,在设计的初

Java进阶学习(5)之设计原则(下)

框架加数据 把数据的硬编码尽可能解成框架加数据的结构 城堡游戏修改后的代码 Room类 1 package com.castle; 2 3 import java.util.HashMap; 4 5 public class Room { 6 private String description; 7 private HashMap<String, Room> exits=new HashMap<String, Room>(); 8 9 10 public Room(String

BaseMongo基类设计

为进一步完善框架应用,本次系列文章主要是介绍如何完善架构功能,以及如何应用架构做一些具体的应用开发.本系列课程可以在github上找到相应资源,具体每篇文章中都会提供链接. 本次介绍的主要是mongo基类的设计,以及应用.相关请查看文章下面链接下载http://5xpan.com/fs/7hueanfgd6h350fe4/(下载链接有收益,请原谅有广告). 如果你嫌弃慢的话,也可以直接去github(https://github.com/tnodejs/BaseMongodb) 主要函数结构 私

Android基类设计方法详解

1 为什么要设计基类 为什么要给程序设计基类呢?主要是出于2个原因,一是方便代码编写,减少重复代码和冗余逻辑,优化代码:二是优化程序架构,降低耦合度,方便拓展.修改. ok,编写代码是程序员的第一步,那么第二步就是要编写高质量的代码,代码能实现功能是一方面,写的优美则是另一方面,这也是我们所有攻城狮们应该追求的境界. 2 设计基类的基本思路 那么,哪些东西我们需要抽象到基类中呢? 2.1 重复的代码:如果一个逻辑是大多数子类都需要使用的 2.2 臭而长的代码:典型的findviewbyid.To

iOS控制器之基类设计

题记 在进入新公司后.经过这一个月的重构项目,终于把项目做到了个人相对满意的程度(还有一种不满意的叫老板的需求,提过多次意见也没用= =!).在这次重构中按照以前的思路设计出了个人觉得比较适用的一个基类.在这里笔者会把此基类基本的设计说明一遍. 基类设计需求 1.在我们搭建框架之初一般会设计一个ViewController基类,并在基类ViewDidLoad中设置一个随机的背景颜色.并通过touch手势来进行界面的跳转,以此来设计最开始的一个界面跳转框架,并通过界面颜色的变幻来验证我们界面跳转是